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,714 @@
|
|
|
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
|
+
"""
|
|
14
|
+
文件名:work_build_conan.py
|
|
15
|
+
功能:编译产品依赖包
|
|
16
|
+
版权信息:华为技术有限公司,版本所有(C) 2019-2020
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
import shutil
|
|
21
|
+
import shlex
|
|
22
|
+
import stat
|
|
23
|
+
import json
|
|
24
|
+
import time
|
|
25
|
+
import subprocess
|
|
26
|
+
import random
|
|
27
|
+
import pathlib
|
|
28
|
+
from multiprocessing import Process, Queue
|
|
29
|
+
from copy import deepcopy
|
|
30
|
+
|
|
31
|
+
import yaml
|
|
32
|
+
from colorama import Fore, Back, Style
|
|
33
|
+
from conans.model.profile import Profile
|
|
34
|
+
|
|
35
|
+
from bmcgo.tasks.task import Task
|
|
36
|
+
from bmcgo.utils.config import Config
|
|
37
|
+
from bmcgo.utils.component_post import ComponentPost
|
|
38
|
+
from bmcgo.utils.component_version_check import ComponentVersionCheck
|
|
39
|
+
from bmcgo import errors, misc
|
|
40
|
+
from bmcgo.utils.tools import Tools
|
|
41
|
+
from bmcgo.errors import BmcGoException
|
|
42
|
+
from bmcgo.component.component_helper import ComponentHelper
|
|
43
|
+
|
|
44
|
+
IBMC_LOCK_FILE = "openubmc.lock"
|
|
45
|
+
SDK_ROOT = "/opt/hi1711sdk"
|
|
46
|
+
SDK_ROOT_MODULE_SYMVERS = os.path.join(SDK_ROOT, "Module.symvers")
|
|
47
|
+
tools = Tools()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class CopyComponent(Process):
|
|
51
|
+
def __init__(self, work: Task, comp: str, profile: Profile):
|
|
52
|
+
super().__init__()
|
|
53
|
+
self.work = work
|
|
54
|
+
self.config = self.work.config
|
|
55
|
+
self.comp = comp
|
|
56
|
+
self.profile = profile
|
|
57
|
+
|
|
58
|
+
def link_recursive_deal(self, file_name, ownership):
|
|
59
|
+
self.work.run_command(f"chown -h {ownership} {file_name}", sudo=True)
|
|
60
|
+
if os.path.islink(os.readlink(file_name)):
|
|
61
|
+
self.link_recursive_deal(os.readlink(file_name), ownership)
|
|
62
|
+
|
|
63
|
+
def run(self):
|
|
64
|
+
self.work.work_name = self.comp
|
|
65
|
+
# 复制组件文件到rootfs中
|
|
66
|
+
# rc.sysinit脚本只允许使用rootfs_user仓库的
|
|
67
|
+
rc_sysinit_path = os.path.join(self.comp, "etc/rc.d/rc.sysinit")
|
|
68
|
+
if self.comp != "rootfs_user" and os.path.isfile(rc_sysinit_path):
|
|
69
|
+
shutil.rmtree(rc_sysinit_path, ignore_errors=True)
|
|
70
|
+
# 由于复制时有很多同名路径,cp命令有概率失败,10次复制尝试
|
|
71
|
+
self._copy_files()
|
|
72
|
+
|
|
73
|
+
# 执行权限控制逻辑
|
|
74
|
+
per_cfg = os.path.join(self.comp, "permissions.ini")
|
|
75
|
+
if not os.path.isfile(per_cfg):
|
|
76
|
+
self.work.warning("权限文件 {} 不存在, 所以无法设置组件 {} 的权限".format(per_cfg, self.comp))
|
|
77
|
+
return
|
|
78
|
+
self.work.info("依据配置文件: {}, 修改权限".format(per_cfg))
|
|
79
|
+
# NOTE 这里的配置时间, 偶发复制未完成, 就开始修改权限
|
|
80
|
+
with open(per_cfg, "r") as fp:
|
|
81
|
+
for line in fp:
|
|
82
|
+
line = line.strip()
|
|
83
|
+
if len(line) == 0:
|
|
84
|
+
continue
|
|
85
|
+
if line.startswith("#"):
|
|
86
|
+
continue
|
|
87
|
+
self.proc_permissions_line(line)
|
|
88
|
+
|
|
89
|
+
def proc_permissions_line(self, line):
|
|
90
|
+
chk = line.split()
|
|
91
|
+
if len(chk) not in (5, 6):
|
|
92
|
+
raise errors.BmcGoException("格式错误行: {}, 固定格式为: name type mode uid gid [os1,os2]".format(line))
|
|
93
|
+
file = os.path.join(self.config.rootfs_path, chk[0])
|
|
94
|
+
if len(chk) == 6:
|
|
95
|
+
host_os = self.profile.settings.get("os")
|
|
96
|
+
is_supported_by_os = host_os in (chk[5].split(","))
|
|
97
|
+
if not is_supported_by_os:
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
if chk[1] == 'f' or chk[1] == "d":
|
|
101
|
+
self.work.run_command("chmod {} {}".format(chk[2], file), sudo=True, command_echo=False,
|
|
102
|
+
command_key=self.comp)
|
|
103
|
+
self.work.run_command("chown {}:{} {}".format(chk[3], chk[4], file), sudo=True, command_echo=False,
|
|
104
|
+
command_key=self.comp)
|
|
105
|
+
if os.path.islink(file):
|
|
106
|
+
self.link_recursive_deal(file, f"{chk[3]}:{chk[4]}")
|
|
107
|
+
elif chk[1] == "r":
|
|
108
|
+
self.work.pipe_command(["sudo find {} -type f ".format(file), " sudo xargs -P 0 -i. chmod {} ."
|
|
109
|
+
.format(chk[2])], command_echo=False)
|
|
110
|
+
self.work.pipe_command(["sudo find {} -type f ".format(file), " sudo xargs -P 0 -i. chown {}:{} ."
|
|
111
|
+
.format(chk[3], chk[4])], command_echo=False)
|
|
112
|
+
elif chk[1] == "rd":
|
|
113
|
+
self.work.pipe_command(["sudo find {} -type d ".format(file), " sudo xargs -P 0 -i. chmod {} ."
|
|
114
|
+
.format(chk[2])], command_echo=False)
|
|
115
|
+
self.work.pipe_command(["sudo find {} -type d ".format(file), " sudo xargs -P 0 -i. chown {}:{} ."
|
|
116
|
+
.format(chk[3], chk[4])], command_echo=False)
|
|
117
|
+
elif chk[1] == "l":
|
|
118
|
+
self.work.run_command("chown -h {}:{} {}".format(chk[3], chk[4], file), sudo=True,
|
|
119
|
+
command_key=self.comp)
|
|
120
|
+
|
|
121
|
+
def _copy_files(self):
|
|
122
|
+
# 由于复制时有很多同名路径,cp命令有概率失败,10次复制尝试
|
|
123
|
+
cmd = "sudo cp -dfr {}/. {}".format(self.comp, self.config.rootfs_path)
|
|
124
|
+
for _ in range(0, 10):
|
|
125
|
+
try:
|
|
126
|
+
# 尝试复制到目标目录,成功则break退出循环
|
|
127
|
+
ret = self.work.run_command(cmd, command_echo=True, ignore_error=True)
|
|
128
|
+
if ret.returncode is not None and ret.returncode == 0:
|
|
129
|
+
return
|
|
130
|
+
except Exception:
|
|
131
|
+
# 失败了打印告警信息,等待后继续尝试
|
|
132
|
+
self.work.run_command("pwd", show_log=True)
|
|
133
|
+
self.work.warning("执行命令 {} 失败, 即将重试".format(cmd))
|
|
134
|
+
time.sleep(0.5 + random.random())
|
|
135
|
+
else:
|
|
136
|
+
# 如果10次都失败了,则报错,并退出
|
|
137
|
+
raise errors.BmcGoException(f"复制 {self.comp} 失败 !!!")
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class ConanLockParse:
|
|
141
|
+
error_str = "Error"
|
|
142
|
+
|
|
143
|
+
def __init__(self, bundle_file_name, work: Task):
|
|
144
|
+
"""
|
|
145
|
+
bundle_file_name: 生成的.bundle文件
|
|
146
|
+
"""
|
|
147
|
+
self.work = work
|
|
148
|
+
# 读取bundle文件生成入度字典
|
|
149
|
+
with open(bundle_file_name, "r") as fp:
|
|
150
|
+
self._bundle = json.load(fp)['lock_bundle']
|
|
151
|
+
self._queue = Queue()
|
|
152
|
+
self._degree = None
|
|
153
|
+
# 防止丢包,已收到包校验
|
|
154
|
+
self._received_list = []
|
|
155
|
+
self._process_list = []
|
|
156
|
+
|
|
157
|
+
def conan_install(self, cmd, com):
|
|
158
|
+
real_cmd = shlex.split(cmd)
|
|
159
|
+
pipe = subprocess.Popen(real_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
160
|
+
# 超时时长1800s
|
|
161
|
+
out, _ = pipe.communicate(timeout=1800)
|
|
162
|
+
if pipe.returncode != 0:
|
|
163
|
+
self.work.error(f"================== {com} 构建失败日志起始位置 ==================")
|
|
164
|
+
self.work.info(out.decode())
|
|
165
|
+
self.work.error(f"================== {com} 构建失败日志结束位置 ==================")
|
|
166
|
+
self._queue.put(self.error_str)
|
|
167
|
+
self._queue.put(self.error_str)
|
|
168
|
+
self._queue.put(self.error_str)
|
|
169
|
+
return
|
|
170
|
+
self._queue.put(com)
|
|
171
|
+
self._queue.put(com)
|
|
172
|
+
self._queue.put(com)
|
|
173
|
+
self.work.info(f"命令 {cmd} " + Fore.GREEN + "执行完成" + Style.RESET_ALL)
|
|
174
|
+
|
|
175
|
+
def wait_task_finished(self):
|
|
176
|
+
# 所有入度为0任务拉起后等待完成消息
|
|
177
|
+
finished_com = self._queue.get()
|
|
178
|
+
# 失败时返回Error传递到主进程
|
|
179
|
+
if finished_com == self.error_str:
|
|
180
|
+
for process in self._process_list:
|
|
181
|
+
if process.is_alive():
|
|
182
|
+
process.terminate()
|
|
183
|
+
raise errors.BmcGoException("conan 组件构建进程接收到错误")
|
|
184
|
+
# 未收到过组件消息,检查收到收到的消息是否在未构建的组件依赖中,是则入度-1
|
|
185
|
+
if finished_com not in self._received_list:
|
|
186
|
+
self._received_list.append(finished_com)
|
|
187
|
+
for b_key in self._bundle.keys():
|
|
188
|
+
key_req = self._bundle[b_key].get("requires")
|
|
189
|
+
if self._degree.get(b_key) is not None and key_req is not None and finished_com in key_req:
|
|
190
|
+
self._degree[b_key] = (self._degree[b_key] - 1 if self._degree[b_key] > 0
|
|
191
|
+
else self._degree[b_key])
|
|
192
|
+
return False
|
|
193
|
+
return True
|
|
194
|
+
|
|
195
|
+
def conan_parallel_build(self, cmd, log_path):
|
|
196
|
+
# 日志目录不存在则新建
|
|
197
|
+
log_path = f"{log_path}/com_log"
|
|
198
|
+
os.makedirs(log_path, exist_ok=True)
|
|
199
|
+
|
|
200
|
+
self._degree = {x: len(self._bundle[x].get('requires')) if self._bundle[x].get('requires') is not None else 0
|
|
201
|
+
for x in self._bundle.keys()}
|
|
202
|
+
|
|
203
|
+
self.work.success(">>>>>>>>>>>>>>>>> 开始构建所有组件 <<<<<<<<<<<<<<<<")
|
|
204
|
+
self.work.info("这些进程将要花费几分钟(2-3分钟), 请耐心等待")
|
|
205
|
+
while self._degree:
|
|
206
|
+
# 深拷贝入度字典,分级拉起构建
|
|
207
|
+
entry_degree_temp_dict = deepcopy(self._degree)
|
|
208
|
+
for com, entry_degree in entry_degree_temp_dict.items():
|
|
209
|
+
if entry_degree != 0:
|
|
210
|
+
continue
|
|
211
|
+
# openubmc作为一个最终组件,不推送(远端没有,直接弹出)
|
|
212
|
+
if com.startswith("openubmc/"):
|
|
213
|
+
self._degree.pop(com)
|
|
214
|
+
break
|
|
215
|
+
cmd_tmp = cmd.replace("com_name", f"{com}")
|
|
216
|
+
t = Process(target=self.conan_install, args=(cmd_tmp, com))
|
|
217
|
+
t.start()
|
|
218
|
+
self._process_list.append(t)
|
|
219
|
+
self.work.info(f"命令 {cmd_tmp} " + Fore.GREEN + "开始" + Style.RESET_ALL)
|
|
220
|
+
# 入度为0的任务构建拉起后弹出
|
|
221
|
+
self._degree.pop(com)
|
|
222
|
+
else:
|
|
223
|
+
while self.wait_task_finished():
|
|
224
|
+
continue
|
|
225
|
+
|
|
226
|
+
self.work.success(">>>>>>>>>>>>>>>>> 所有组件构建成功 <<<<<<<<<<<<<<<<")
|
|
227
|
+
return 0
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class TaskClass(Task):
|
|
231
|
+
# 当前软件包的组件依赖列表
|
|
232
|
+
depdencies = []
|
|
233
|
+
|
|
234
|
+
def __init__(self, config: Config, work_name=""):
|
|
235
|
+
super(TaskClass, self).__init__(config, work_name)
|
|
236
|
+
self.update_path()
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def subsys_dir(self):
|
|
240
|
+
subsys = os.path.join(self.config.code_path, "subsys")
|
|
241
|
+
if self.config.stage == misc.StageEnum.STAGE_STABLE.value:
|
|
242
|
+
subsys = os.path.join(subsys, misc.StageEnum.STAGE_STABLE.value)
|
|
243
|
+
else:
|
|
244
|
+
subsys = os.path.join(subsys, misc.StageEnum.STAGE_RC.value)
|
|
245
|
+
return subsys
|
|
246
|
+
|
|
247
|
+
def find_conan_package_and_write(self, search, comps, file_handler, stage):
|
|
248
|
+
if search.find("/") < 0:
|
|
249
|
+
search += "/"
|
|
250
|
+
for comp in comps:
|
|
251
|
+
if comp.startswith(search):
|
|
252
|
+
if stage == misc.StageEnum.STAGE_STABLE.value \
|
|
253
|
+
and not comp.endswith(f"/{misc.StageEnum.STAGE_STABLE.value}"):
|
|
254
|
+
err_msg = f"组件包 {comp} user/channel 配置错误, 必须以 \"{misc.StageEnum.STAGE_STABLE.value}\" 作为结尾, 终止构建"
|
|
255
|
+
raise errors.BmcGoException(err_msg)
|
|
256
|
+
if stage != misc.StageEnum.STAGE_DEV.value and comp.endswith(f"/{misc.StageEnum.STAGE_DEV.value}"):
|
|
257
|
+
err_msg = f"组件包 {comp} user/channel 配置错误, 必须以 \"{stage}\" 作为结尾, 终止构建"
|
|
258
|
+
raise errors.BmcGoException(err_msg)
|
|
259
|
+
self.add_new_dependencies(comp, file_handler)
|
|
260
|
+
return
|
|
261
|
+
raise errors.ConfigException(f"未知组件: {search}, 请检查配置 !!!")
|
|
262
|
+
|
|
263
|
+
def update_path(self):
|
|
264
|
+
# conan source folder
|
|
265
|
+
self.conan_source = os.path.join(self.config.temp_path,
|
|
266
|
+
f"conan_source_{self.config.build_type}_{self.config.stage}/openubmc")
|
|
267
|
+
# conan install folder
|
|
268
|
+
self.conan_install = os.path.join(self.config.build_path, "conan_install")
|
|
269
|
+
# openubmc install folder
|
|
270
|
+
self.openubmc_ins_dir = os.path.join(self.conan_install, "openubmc")
|
|
271
|
+
# openubmc top rootfs folder
|
|
272
|
+
self.top_rootfs_dir = os.path.join(self.conan_install, "rootfs")
|
|
273
|
+
self.board_option = ""
|
|
274
|
+
self.skip_package = False
|
|
275
|
+
|
|
276
|
+
def mkdir_work_path(self):
|
|
277
|
+
self.run_command(f"rm -rf {self.conan_source}", sudo=True)
|
|
278
|
+
os.makedirs(self.conan_source, exist_ok=True)
|
|
279
|
+
self.run_command(f"rm -rf {self.conan_install}", sudo=True)
|
|
280
|
+
os.makedirs(self.conan_install, exist_ok=True)
|
|
281
|
+
self.run_command(f"rm -rf {self.openubmc_ins_dir}", sudo=True)
|
|
282
|
+
self.run_command(f"rm -rf {self.top_rootfs_dir}", sudo=True)
|
|
283
|
+
self.run_command(f"rm -rf {self.config.rootfs_path}", sudo=True)
|
|
284
|
+
os.makedirs(self.config.rootfs_path)
|
|
285
|
+
|
|
286
|
+
def set_build_type(self, build_type):
|
|
287
|
+
self.config.set_build_type(build_type)
|
|
288
|
+
self.update_path()
|
|
289
|
+
|
|
290
|
+
def set_stage(self, stage):
|
|
291
|
+
self.config.set_stage(stage)
|
|
292
|
+
self.update_path()
|
|
293
|
+
|
|
294
|
+
def set_from_source(self, value):
|
|
295
|
+
if value:
|
|
296
|
+
self.config.set_from_source(True)
|
|
297
|
+
else:
|
|
298
|
+
self.config.set_from_source(False)
|
|
299
|
+
|
|
300
|
+
def set_skip_package(self, value):
|
|
301
|
+
if value:
|
|
302
|
+
self.skip_package = True
|
|
303
|
+
else:
|
|
304
|
+
self.skip_package = False
|
|
305
|
+
|
|
306
|
+
def package_dependencies_parse(self, default_component: list):
|
|
307
|
+
"""解析manufacture或者tosupporte配置,不同的包设置不同组件的不同编译选项
|
|
308
|
+
参数:
|
|
309
|
+
default_component (list): manifest的标准配置
|
|
310
|
+
返回值:
|
|
311
|
+
default_component (list): 依据manufacture配置处理后配置
|
|
312
|
+
"""
|
|
313
|
+
# 默认情况下,不配置额外的options
|
|
314
|
+
if self.config.manufacture_code is None and self.config.tosupporte_code == "default":
|
|
315
|
+
return default_component
|
|
316
|
+
if self.config.manufacture_code is not None:
|
|
317
|
+
package_dependencies = self.get_manufacture_config(
|
|
318
|
+
f"manufacture/{self.config.manufacture_code}/dependencies")
|
|
319
|
+
elif self.config.tosupporte_code != "default":
|
|
320
|
+
package_dependencies = self.get_manufacture_config(f"tosupporte/{self.config.tosupporte_code}/dependencies")
|
|
321
|
+
if package_dependencies is None:
|
|
322
|
+
return default_component
|
|
323
|
+
components = tools.merge_dependencies(package_dependencies, default_component)
|
|
324
|
+
self.debug(f"组件处理结束后: {components}")
|
|
325
|
+
return components
|
|
326
|
+
|
|
327
|
+
def add_new_dependencies(self, conan, file_handler):
|
|
328
|
+
file_handler.write(" - conan: \"{}\"\n".format(conan))
|
|
329
|
+
self.success(f"获取到依赖: {conan}")
|
|
330
|
+
self.depdencies.append(conan)
|
|
331
|
+
|
|
332
|
+
def merge_manifest(self):
|
|
333
|
+
comps = []
|
|
334
|
+
for f in os.listdir(self.subsys_dir):
|
|
335
|
+
with open(os.path.join(self.subsys_dir, f)) as fp:
|
|
336
|
+
yml = yaml.safe_load(fp)
|
|
337
|
+
deps = yml.get('dependencies')
|
|
338
|
+
for dep in deps:
|
|
339
|
+
conan = dep.get(misc.CONAN)
|
|
340
|
+
if conan:
|
|
341
|
+
comps.append(conan)
|
|
342
|
+
self.debug("依赖列表: {}".format(comps))
|
|
343
|
+
# 重建新的依赖关系
|
|
344
|
+
# 从单板目录manifest.yml,与subsys/<stage>目录下的组件合并
|
|
345
|
+
new_fd = os.fdopen(os.open("manifest.yml", os.O_WRONLY | os.O_CREAT,
|
|
346
|
+
stat.S_IWUSR | stat.S_IRUSR), 'w')
|
|
347
|
+
new_fd.write("base:\n")
|
|
348
|
+
ver = self.get_manufacture_config("base/version")
|
|
349
|
+
|
|
350
|
+
new_fd.write(f" version: \"{ver}@{tools.conan_user}/{misc.StageEnum.STAGE_RC.value}\"\n")
|
|
351
|
+
self.info(f"包版本号: {ver}")
|
|
352
|
+
|
|
353
|
+
new_fd.write("dependencies:\n")
|
|
354
|
+
deps = self._get_dependencies_pkg()
|
|
355
|
+
|
|
356
|
+
# 如果是打包,依赖信息调整
|
|
357
|
+
deps = self.package_dependencies_parse(deps)
|
|
358
|
+
# 由于manifest.yml当中有对于此的新的配置,此处将配置读出,并重新分配
|
|
359
|
+
skynet_with_enable_luajit = False
|
|
360
|
+
for dep in deps:
|
|
361
|
+
conan = dep.get(misc.CONAN)
|
|
362
|
+
if not conan:
|
|
363
|
+
continue
|
|
364
|
+
if conan.find("@") > 0:
|
|
365
|
+
self.add_new_dependencies(conan, new_fd)
|
|
366
|
+
elif conan.find("/") > 0:
|
|
367
|
+
stage = self.config.stage
|
|
368
|
+
if stage != misc.StageEnum.STAGE_STABLE.value:
|
|
369
|
+
stage = misc.StageEnum.STAGE_RC.value
|
|
370
|
+
conan += f"@{tools.conan_user}/{stage}"
|
|
371
|
+
self.add_new_dependencies(conan, new_fd)
|
|
372
|
+
else:
|
|
373
|
+
self.find_conan_package_and_write(conan, comps, new_fd, self.config.stage)
|
|
374
|
+
options = dep.get("options", {})
|
|
375
|
+
name = conan.split("/")[0]
|
|
376
|
+
for key, val in options.items():
|
|
377
|
+
self.board_option = self.board_option + " -o {}:{}={}".format(name, key, val)
|
|
378
|
+
# skynet特殊处理:manifest.yml指定enable_luajit特性时需要覆盖用户输入
|
|
379
|
+
if name == "skynet" and key == "enable_luajit":
|
|
380
|
+
self.warning(f"根据manifest.yml配置,当前产品的enable_luajit配置为{val},忽略命令行指定的-jit参数")
|
|
381
|
+
self.config.set_enable_luajit(val)
|
|
382
|
+
skynet_with_enable_luajit = True
|
|
383
|
+
# 当使能Luajit又未向skynet传递enable_luajit配置项时需要添加使能参数
|
|
384
|
+
if not skynet_with_enable_luajit and self.config.enable_luajit:
|
|
385
|
+
self.board_option += f" -o skynet:enable_luajit={self.config.enable_luajit}"
|
|
386
|
+
self.merge_0502_default_options()
|
|
387
|
+
sha256 = Tools.sha256sum(SDK_ROOT_MODULE_SYMVERS)
|
|
388
|
+
self.board_option += " -o *:module_symvers={}".format(sha256)
|
|
389
|
+
new_fd.close()
|
|
390
|
+
|
|
391
|
+
def merge_0502_default_options(self):
|
|
392
|
+
if self.config.manufacture_code:
|
|
393
|
+
default_options_path = f"manufacture/{self.config.manufacture_code}/default_options"
|
|
394
|
+
default_options = self.get_manufacture_config(default_options_path, {})
|
|
395
|
+
for key, val in default_options.items():
|
|
396
|
+
self.board_option += f" -o *:{key}={val}"
|
|
397
|
+
|
|
398
|
+
def package_info_gen(self, bundle_file, dst_file):
|
|
399
|
+
with open(bundle_file, "r") as fp:
|
|
400
|
+
bundle = json.load(fp)['lock_bundle']
|
|
401
|
+
require_list = list(bundle.keys())
|
|
402
|
+
list.sort(require_list)
|
|
403
|
+
package_info_list = deepcopy(require_list)
|
|
404
|
+
self.run_command(f"rm -rf {dst_file}", sudo=True)
|
|
405
|
+
temp_dst_file = f"{self.config.rootfs_path}/{os.path.basename(dst_file)}"
|
|
406
|
+
with os.fdopen(os.open(temp_dst_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, stat.S_IWUSR | stat.S_IRUSR |
|
|
407
|
+
stat.S_IWGRP | stat.S_IRGRP | stat.S_IWOTH | stat.S_IROTH), 'w') as fp:
|
|
408
|
+
for package in require_list:
|
|
409
|
+
if "openubmc/" not in package:
|
|
410
|
+
fp.write(f"{package.split('#')[0]}\n")
|
|
411
|
+
else:
|
|
412
|
+
package_info_list.remove(package)
|
|
413
|
+
fp.close()
|
|
414
|
+
self.run_command(f"cp -df {temp_dst_file} {dst_file}", sudo=True)
|
|
415
|
+
self.run_command(f"rm -rf {temp_dst_file}", sudo=True)
|
|
416
|
+
|
|
417
|
+
def sensitive_data_conf_gen(self, comps, dst_file):
|
|
418
|
+
self.run_command(f"rm -rf {dst_file}", sudo=True)
|
|
419
|
+
temp_dst_file = f"{self.config.rootfs_path}/{os.path.basename(dst_file)}"
|
|
420
|
+
output = {
|
|
421
|
+
"TemporaryPer": {},
|
|
422
|
+
"ResetPer": {},
|
|
423
|
+
"PoweroffPer": {},
|
|
424
|
+
"PermanentPer": {}
|
|
425
|
+
}
|
|
426
|
+
for comp in comps:
|
|
427
|
+
try:
|
|
428
|
+
output = self.proc_comp(comp, output)
|
|
429
|
+
except Exception as e:
|
|
430
|
+
self.warning(f"分析组件 {comp} 的 model.json 失败, 失败信息:{e}")
|
|
431
|
+
|
|
432
|
+
with os.fdopen(os.open(temp_dst_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
|
|
433
|
+
stat.S_IWUSR | stat.S_IRUSR), 'w') as fp:
|
|
434
|
+
json.dump(output, fp, sort_keys=True)
|
|
435
|
+
self.run_command(f"cp -df {temp_dst_file} {dst_file}", sudo=True)
|
|
436
|
+
self.run_command(f"rm -rf {temp_dst_file}", sudo=True)
|
|
437
|
+
|
|
438
|
+
def proc_sensitive(self, per_type, props, table_name, output):
|
|
439
|
+
for prop_name, prop_data in props.items():
|
|
440
|
+
for item in prop_data.get("usage", []):
|
|
441
|
+
if item in output:
|
|
442
|
+
per_type = item
|
|
443
|
+
break
|
|
444
|
+
is_sensitive = prop_data.get("sensitive", False)
|
|
445
|
+
if per_type not in output or not is_sensitive:
|
|
446
|
+
continue
|
|
447
|
+
output[per_type][table_name] = output[per_type].get(table_name, {})
|
|
448
|
+
output[per_type][table_name][prop_name] = True
|
|
449
|
+
return output
|
|
450
|
+
|
|
451
|
+
def proc_comp(self, comp, output):
|
|
452
|
+
model_file = os.path.join(self.conan_install, comp, "include", "mds", "model.json")
|
|
453
|
+
if not os.path.isfile(model_file):
|
|
454
|
+
return output
|
|
455
|
+
with open(model_file, "r") as fp:
|
|
456
|
+
content = json.load(fp)
|
|
457
|
+
for class_data in content.values():
|
|
458
|
+
per_type = class_data.get("tableType", "")
|
|
459
|
+
table_name = class_data.get("tableName", "")
|
|
460
|
+
if not table_name:
|
|
461
|
+
continue
|
|
462
|
+
class_props = [class_data.get("properties", {})]
|
|
463
|
+
for intf_data in class_data.get("interfaces", {}).values():
|
|
464
|
+
class_props.append(intf_data.get("properties", {}))
|
|
465
|
+
for props in class_props:
|
|
466
|
+
output = self.proc_sensitive(per_type, props, table_name, output)
|
|
467
|
+
return output
|
|
468
|
+
|
|
469
|
+
def calc_options(self):
|
|
470
|
+
if self.config.build_type == "dt":
|
|
471
|
+
options = "-s build_type=Dt"
|
|
472
|
+
else:
|
|
473
|
+
if self.config.build_type == "debug":
|
|
474
|
+
options = "-s build_type=Debug"
|
|
475
|
+
else:
|
|
476
|
+
options = "-s build_type=Release"
|
|
477
|
+
|
|
478
|
+
if self.config.enable_arm_gcov:
|
|
479
|
+
options += " -o *:gcov=True"
|
|
480
|
+
return options
|
|
481
|
+
|
|
482
|
+
def install_ibmc(self):
|
|
483
|
+
profile_file = os.path.join(self.tools.conan_profiles_dir, self.config.profile)
|
|
484
|
+
if not os.path.isfile(profile_file):
|
|
485
|
+
raise BmcGoException(f"{profile_file} 文件不存在")
|
|
486
|
+
|
|
487
|
+
options = self.calc_options()
|
|
488
|
+
append_cmd = f"-r {self.config.remote}" if self.config.remote else ""
|
|
489
|
+
# 构建前删除锁文件
|
|
490
|
+
if os.path.isfile(IBMC_LOCK_FILE):
|
|
491
|
+
os.unlink(IBMC_LOCK_FILE)
|
|
492
|
+
# 依据选项生成openubmc.lock和openubmc.bundle文件
|
|
493
|
+
cmd = f"conan lock create conanfile.py --lockfile-out=openubmc.lock -pr={self.config.profile} "
|
|
494
|
+
cmd += f"-pr:b profile.dt.ini {append_cmd} {options} {self.board_option} --build"
|
|
495
|
+
if self.config.from_source:
|
|
496
|
+
self.run_command(cmd)
|
|
497
|
+
cmd = f"conan install com_name -if={self.conan_install} --lockfile=openubmc.lock "
|
|
498
|
+
cmd += f"{append_cmd} --build=com_name"
|
|
499
|
+
else:
|
|
500
|
+
cmd += "=missing"
|
|
501
|
+
self.run_command(cmd)
|
|
502
|
+
cmd = f"conan install com_name -if={self.conan_install} --lockfile=openubmc.lock --build=missing "
|
|
503
|
+
cmd += f"{append_cmd}"
|
|
504
|
+
self.run_command("conan lock bundle create openubmc.lock --bundle-out=openubmc.bundle")
|
|
505
|
+
# 优化缓存构建时长:非源码构建时先尝试直接构建一次,失败时构建所有依赖组件
|
|
506
|
+
ret = -1
|
|
507
|
+
install_cmd = f"conan install conanfile.py --lockfile=openubmc.lock -if={self.conan_install} -g deploy"
|
|
508
|
+
if not self.config.from_source:
|
|
509
|
+
self.info(">>>>>>>>>>>>> 尝试直接安装 >>>>>>>>>>>>>>>>>>")
|
|
510
|
+
ret = 0
|
|
511
|
+
try:
|
|
512
|
+
self.run_command(install_cmd, command_echo=True, warn_log="缓存安装失败,可能缺少某个依赖项制品,开始从源码构建缺失的软件包")
|
|
513
|
+
except Exception:
|
|
514
|
+
ret = -1
|
|
515
|
+
if ret != 0:
|
|
516
|
+
bundle_parse = ConanLockParse("openubmc.bundle", self)
|
|
517
|
+
bundle_parse.conan_parallel_build(cmd, self.config.build_path)
|
|
518
|
+
self.run_command(install_cmd, command_echo=True)
|
|
519
|
+
shutil.copyfile(IBMC_LOCK_FILE, f"{self.conan_install}/conan.lock")
|
|
520
|
+
# 检查使用到的组件是否都在单板目录 manifest.yml 中配置了
|
|
521
|
+
component_check = ComponentVersionCheck(manifest_yml="manifest.yml", ibmc_lock=IBMC_LOCK_FILE)
|
|
522
|
+
component_check.run()
|
|
523
|
+
self.clean_luac_out()
|
|
524
|
+
|
|
525
|
+
def deploy(self):
|
|
526
|
+
src = os.path.join(self.config.code_path, "conan_index/openubmc")
|
|
527
|
+
shutil.copytree(src, self.conan_source, dirs_exist_ok=True)
|
|
528
|
+
openubmc_dir = os.path.join(self.conan_source, "all")
|
|
529
|
+
self.chdir(openubmc_dir)
|
|
530
|
+
# 复制manifest.yml文件
|
|
531
|
+
self.merge_manifest()
|
|
532
|
+
# 下载组件构建脚本
|
|
533
|
+
ComponentHelper.download_recipes(self.depdencies, self.tools, self.config.remote_list)
|
|
534
|
+
# 下载skynet
|
|
535
|
+
self.install_luac_or_luajit()
|
|
536
|
+
|
|
537
|
+
# 复制全局定制rootfs到conan install目录
|
|
538
|
+
top_rootfs = os.path.join(self.config.code_path, "rootfs")
|
|
539
|
+
self.info("复制 {} 到 conan 安装目录".format(top_rootfs))
|
|
540
|
+
self.run_command(f"rm -rf {self.top_rootfs_dir}")
|
|
541
|
+
self.run_command(f"cp -rf {top_rootfs} {self.top_rootfs_dir}")
|
|
542
|
+
|
|
543
|
+
# 复制单板目录下的权限配置和rootfs文件
|
|
544
|
+
rootfs_dir = os.path.join(self.config.board_path, "rootfs")
|
|
545
|
+
if os.path.isdir(rootfs_dir):
|
|
546
|
+
self.run_command(f"rm -rf {self.openubmc_ins_dir}")
|
|
547
|
+
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
|
+
else:
|
|
551
|
+
os.makedirs(self.openubmc_ins_dir)
|
|
552
|
+
per_file = os.path.join(self.config.board_path, "permissions.ini")
|
|
553
|
+
if os.path.isfile(per_file):
|
|
554
|
+
shutil.copy(per_file, self.openubmc_ins_dir)
|
|
555
|
+
|
|
556
|
+
self.install_ibmc()
|
|
557
|
+
|
|
558
|
+
def clean_luac_out(self):
|
|
559
|
+
# 清理冗余文件luac.out
|
|
560
|
+
self.chdir(self.conan_install)
|
|
561
|
+
for root, _, files in os.walk("."):
|
|
562
|
+
for file in files:
|
|
563
|
+
if "luac.out" == file:
|
|
564
|
+
os.remove(os.path.join(root, file))
|
|
565
|
+
|
|
566
|
+
def link_recursive_deal(self, file_name, ownership):
|
|
567
|
+
self.run_command(f"chown -h {ownership} {file_name}", sudo=True)
|
|
568
|
+
if os.path.islink(os.readlink(file_name)):
|
|
569
|
+
self.link_recursive_deal(os.readlink(file_name), ownership)
|
|
570
|
+
|
|
571
|
+
def package_lock(self):
|
|
572
|
+
self.chdir(self.conan_install)
|
|
573
|
+
inner_path = self.config.inner_path
|
|
574
|
+
os.makedirs(inner_path, exist_ok=True)
|
|
575
|
+
self.run_command(f'cp -f conan.lock {os.path.join(inner_path, f"package_{self.config.board_name}.lock")}')
|
|
576
|
+
self.run_command(f'cp -f conan.lock {os.path.join(self.config.output_path, f"package.lock")}')
|
|
577
|
+
|
|
578
|
+
def copy_components(self, comps: list, profile: Profile):
|
|
579
|
+
# 优先处理rootfs
|
|
580
|
+
p = CopyComponent(self, "rootfs", profile)
|
|
581
|
+
p.run()
|
|
582
|
+
# 打印组件清单
|
|
583
|
+
self.info(f"组件列表: {comps}")
|
|
584
|
+
pools = []
|
|
585
|
+
for comp in comps:
|
|
586
|
+
p = CopyComponent(self, comp, profile)
|
|
587
|
+
p.start()
|
|
588
|
+
pools.append(p)
|
|
589
|
+
|
|
590
|
+
while pools:
|
|
591
|
+
time.sleep(0.01)
|
|
592
|
+
for p in pools:
|
|
593
|
+
if p.is_alive():
|
|
594
|
+
continue
|
|
595
|
+
if p.exitcode is not None and p.exitcode != 0:
|
|
596
|
+
raise errors.BmcGoException(f"复制组件 ({p.comp}) 失败, 退出码: {p.exitcode}")
|
|
597
|
+
pools.remove(p)
|
|
598
|
+
# 最后处理openubmc
|
|
599
|
+
p = CopyComponent(self, "openubmc", profile)
|
|
600
|
+
p.run()
|
|
601
|
+
|
|
602
|
+
def package(self):
|
|
603
|
+
self.chdir(self.conan_install)
|
|
604
|
+
self.run_command(f"sudo rm -rf {self.config.rootfs_path}")
|
|
605
|
+
os.makedirs(self.config.rootfs_path)
|
|
606
|
+
profile, _ = self.get_profile_config()
|
|
607
|
+
comps = []
|
|
608
|
+
for dirname in os.listdir("."):
|
|
609
|
+
if not os.path.isdir(dirname):
|
|
610
|
+
continue
|
|
611
|
+
if dirname != "rootfs" and dirname != "openubmc":
|
|
612
|
+
comps.append(dirname)
|
|
613
|
+
|
|
614
|
+
self.copy_components(comps, profile)
|
|
615
|
+
|
|
616
|
+
# 运行组件定制化文件
|
|
617
|
+
for comp in comps:
|
|
618
|
+
cust = os.path.join(self.conan_install, comp, "include", "customization.py")
|
|
619
|
+
if not os.path.isfile(cust):
|
|
620
|
+
continue
|
|
621
|
+
self.info(f"开始执行 {comp}/include/customization.py")
|
|
622
|
+
post = ComponentPost(self.config, os.path.join(self.conan_install, comp), profile)
|
|
623
|
+
post.post_work(self.config.rootfs_path, "post_image")
|
|
624
|
+
|
|
625
|
+
self.chdir(self.config.rootfs_path)
|
|
626
|
+
self.package_info_gen(f"{self.conan_source}/all/openubmc.bundle", "etc/package_info")
|
|
627
|
+
self.sensitive_data_conf_gen(comps, "opt/bmc/trust/sensitive_data.json")
|
|
628
|
+
if os.path.isfile("permissions.ini"):
|
|
629
|
+
os.unlink("permissions.ini")
|
|
630
|
+
|
|
631
|
+
def prepare_luac_for_luacov(self, luac):
|
|
632
|
+
"""
|
|
633
|
+
对luac进行打桩,统计覆盖率场景lua文件如果是字节码将无法统计到具体的行覆盖信息
|
|
634
|
+
"""
|
|
635
|
+
luac_cov = f"{self.conan_home}/bin/luac.c"
|
|
636
|
+
with os.fdopen(os.open(luac_cov, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
|
|
637
|
+
stat.S_IWUSR | stat.S_IRUSR), 'w') as f:
|
|
638
|
+
luac_str = "int main(int argc, char* argv[]) {return 0;}"
|
|
639
|
+
f.write(luac_str)
|
|
640
|
+
|
|
641
|
+
if os.path.isfile(luac_cov):
|
|
642
|
+
self.run_command(f"gcc {luac_cov} -o {luac}", sudo=True)
|
|
643
|
+
self.run_command(f"rm {luac_cov}", sudo=True)
|
|
644
|
+
|
|
645
|
+
def install_luac_or_luajit(self):
|
|
646
|
+
conan_bin = os.path.join(self.conan_home, "bin")
|
|
647
|
+
if not os.path.isdir(conan_bin):
|
|
648
|
+
os.makedirs(conan_bin)
|
|
649
|
+
|
|
650
|
+
ld_library_path = conan_bin + ":" + os.environ.get("LD_LIBRARY_PATH", "")
|
|
651
|
+
os.environ["LD_LIBRARY_PATH"] = ld_library_path
|
|
652
|
+
path = conan_bin + ":" + os.environ.get("PATH", "")
|
|
653
|
+
os.environ["PATH"] = path
|
|
654
|
+
os.environ["LUA_PATH"] = f"{conan_bin}/?.lua"
|
|
655
|
+
|
|
656
|
+
if self.config.build_type == "dt":
|
|
657
|
+
return
|
|
658
|
+
luajit_pkg = None
|
|
659
|
+
for dep in self.depdencies:
|
|
660
|
+
if dep.startswith("luajit/"):
|
|
661
|
+
luajit_pkg = dep
|
|
662
|
+
if luajit_pkg is None:
|
|
663
|
+
raise errors.BmcGoException("luajit是必要依赖,未找到正确的luajit包,请确保manifest.yml正确配置luajit")
|
|
664
|
+
luajit_flag = luajit_pkg.split("@")[0].replace("/", "_")
|
|
665
|
+
luajit_flag = os.path.join(conan_bin, luajit_flag)
|
|
666
|
+
luac = f"{conan_bin}/luajit"
|
|
667
|
+
luac_back = f"{conan_bin}/luajit_back"
|
|
668
|
+
|
|
669
|
+
self.config.conan_parallel_lock.acquire()
|
|
670
|
+
# luajit版本一致且luac_back/luajit_back存在时赋权即可
|
|
671
|
+
if os.path.isfile(luajit_flag) and os.path.isfile(luac_back):
|
|
672
|
+
self.link(luac_back, luac)
|
|
673
|
+
else:
|
|
674
|
+
Tools.clean_conan_bin(conan_bin)
|
|
675
|
+
append_cmd = f"-r {self.config.remote}" if self.config.remote else ""
|
|
676
|
+
self.run_command(f"conan install {luajit_pkg} {append_cmd}" +
|
|
677
|
+
" -pr profile.dt.ini -if=temp/.deploy -g deploy")
|
|
678
|
+
cmd = f"cp temp/.deploy/luajit/usr/bin/luajit {conan_bin}"
|
|
679
|
+
self.run_command(cmd)
|
|
680
|
+
cmd = f"cp temp/.deploy/luajit/usr/lib64/liblua.so {conan_bin}"
|
|
681
|
+
self.run_command(cmd)
|
|
682
|
+
cmd = f"cp -r temp/.deploy/luajit/usr/bin/jit {conan_bin}"
|
|
683
|
+
self.run_command(cmd)
|
|
684
|
+
self.link(luac, luac_back)
|
|
685
|
+
# 仅在覆盖率使能场景下,对luac进行打桩
|
|
686
|
+
if self.config.enable_arm_gcov:
|
|
687
|
+
self.prepare_luac_for_luacov(luac)
|
|
688
|
+
os.chmod(luac, stat.S_IRWXU)
|
|
689
|
+
luajit2luac = shutil.which("luajit2luac.sh")
|
|
690
|
+
cmd = f"cp {luajit2luac} {conan_bin}/luac"
|
|
691
|
+
self.run_command(cmd)
|
|
692
|
+
pathlib.Path(luajit_flag).touch(0o600, exist_ok=True)
|
|
693
|
+
self.config.conan_parallel_lock.release()
|
|
694
|
+
|
|
695
|
+
def run(self):
|
|
696
|
+
self.mkdir_work_path()
|
|
697
|
+
self.tools.clean_locks()
|
|
698
|
+
self.deploy()
|
|
699
|
+
self.package_lock()
|
|
700
|
+
if not self.skip_package:
|
|
701
|
+
self.package()
|
|
702
|
+
|
|
703
|
+
def _get_dependencies_pkg(self):
|
|
704
|
+
deps = self.get_manufacture_config('dependencies', [])
|
|
705
|
+
if self.config.enable_arm_gcov:
|
|
706
|
+
dt_deps = self.get_manufacture_config("dt_dependencies", [])
|
|
707
|
+
for dep in dt_deps:
|
|
708
|
+
deps.append(dep)
|
|
709
|
+
# 只有非CI场景的个人构建支持调测包
|
|
710
|
+
if self.config.enable_debug_model and "CLOUD_BUILD_RECORD_ID" not in os.environ:
|
|
711
|
+
dt_deps = self.get_manufacture_config("debug_dependencies", [])
|
|
712
|
+
for dep in dt_deps:
|
|
713
|
+
deps.append(dep)
|
|
714
|
+
return deps
|