lbkit 0.9.8__tar.gz → 0.9.10__tar.gz
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.
- {lbkit-0.9.8/lbkit.egg-info → lbkit-0.9.10}/PKG-INFO +1 -1
- lbkit-0.9.10/lbkit/__init__.py +2 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/component/build.py +11 -17
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/component/test.py +38 -14
- lbkit-0.9.10/lbkit/download_cache.py +112 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/misc.py +1 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/image_maker/make_qemu_image.py +25 -14
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/task.py +6 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/task_build_manifest.py +13 -15
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/task_build_rootfs.py +116 -86
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/task_download.py +34 -15
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tools.py +8 -1
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/ukr/build.py +1 -0
- lbkit-0.9.10/lbkit/utils/fakeroot.py +240 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/utils/images/emmc.py +1 -7
- {lbkit-0.9.8 → lbkit-0.9.10/lbkit.egg-info}/PKG-INFO +1 -1
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit.egg-info/SOURCES.txt +2 -0
- lbkit-0.9.8/lbkit/__init__.py +0 -2
- {lbkit-0.9.8 → lbkit-0.9.10}/AUTHORS +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/LICENSE +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/MANIFEST.in +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/README.md +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/build_conan_parallel.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/ci_robot/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/cli.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/codegen.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/ctype_defination.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/idf_interface.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/renderer.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/template/client.c.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/template/client.h.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/template/interface.c.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/template/public.c.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/template/public.h.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/template/server.c.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/codegen/template/server.h.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/component/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/component/arg_parser.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/component/template/conanbase.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/component/template/deploy.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/errors.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/helper.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/lbkit.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/log.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/config.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/executor.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/image_maker/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/image_maker/make_image.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/image_maker/make_rockchip_image.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/task_build_image.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/task_build_prepare.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/template/conanfile.py.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/tasks/template/rootfs.py.mako +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/ukr/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/utils/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/utils/env_detector.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit/utils/images/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit.egg-info/dependency_links.txt +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit.egg-info/entry_points.txt +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit.egg-info/requires.txt +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/lbkit.egg-info/top_level.txt +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/setup.cfg +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/setup.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/test/__init__.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/test/test_codegen.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/test/test_config.py +0 -0
- {lbkit-0.9.8 → lbkit-0.9.10}/test/test_helper.py +0 -0
|
@@ -33,29 +33,23 @@ def _clang_format_file(args):
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
class DeployComponent():
|
|
36
|
-
def __init__(self, package_ref, package_id, rootfs_dir):
|
|
36
|
+
def __init__(self, package_ref, package_id, rootfs_dir, package_folder=None):
|
|
37
37
|
self.package_ref = package_ref
|
|
38
38
|
self.package_id = package_id
|
|
39
39
|
self.rootfs_dir = rootfs_dir
|
|
40
|
+
self.package_folder = package_folder
|
|
40
41
|
|
|
41
42
|
def run(self):
|
|
42
43
|
if self.package_ref.startswith("deploy"):
|
|
43
44
|
return
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
if self.package_folder:
|
|
46
|
+
package_folder = self.package_folder
|
|
47
|
+
else:
|
|
48
|
+
cmd = f"conan cache path {self.package_ref}:{self.package_id}"
|
|
49
|
+
package_folder = tools.run(cmd).stdout.strip()
|
|
46
50
|
log.info(f">>>> deploy {self.package_ref}")
|
|
47
|
-
cmd = f"
|
|
48
|
-
|
|
49
|
-
while cnt > 0:
|
|
50
|
-
try:
|
|
51
|
-
cnt -= 1
|
|
52
|
-
tools.exec(cmd)
|
|
53
|
-
return
|
|
54
|
-
except Exception as e:
|
|
55
|
-
if cnt == 0:
|
|
56
|
-
log.warn("Copy failed, msg: " + str(e))
|
|
57
|
-
raise e
|
|
58
|
-
log.info("Copy {self.package_ref} failed, try again")
|
|
51
|
+
cmd = f"rsync -aHK {package_folder}/ {self.rootfs_dir}"
|
|
52
|
+
tools.exec(cmd, verbose=True)
|
|
59
53
|
|
|
60
54
|
|
|
61
55
|
class BuildComponent():
|
|
@@ -255,7 +249,7 @@ class BuildComponent():
|
|
|
255
249
|
continue
|
|
256
250
|
if ref.startswith(self.package):
|
|
257
251
|
self.package_id = id
|
|
258
|
-
dep = DeployComponent(ref, id, self.rootfs_dir)
|
|
252
|
+
dep = DeployComponent(ref, id, self.rootfs_dir, info.get("package_folder"))
|
|
259
253
|
pool.apply_async(dep.run, error_callback=self._copy_failed)
|
|
260
254
|
pool.close()
|
|
261
255
|
pool.join()
|
|
@@ -280,7 +274,7 @@ class BuildComponent():
|
|
|
280
274
|
cmd = f"conan create {self.base_cmd} --build='{self.name}/*'"
|
|
281
275
|
tools.exec(cmd, verbose=True)
|
|
282
276
|
|
|
283
|
-
graph_cmd = f"conan
|
|
277
|
+
graph_cmd = f"conan install . {self.base_cmd} --lockfile={self.lockfile} -f json"
|
|
284
278
|
tools.pipe([graph_cmd], out_file=self.graphfile)
|
|
285
279
|
|
|
286
280
|
log.success(f"start deploy {self.package} and is's dependency packages")
|
|
@@ -66,13 +66,27 @@ class TestComponent():
|
|
|
66
66
|
index_file = os.path.join(coverage_dir, "html/index.html")
|
|
67
67
|
with open(index_file, "r") as fp:
|
|
68
68
|
content = fp.read()
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
|
|
70
|
+
# LCOV版本间HTML格式差异:
|
|
71
|
+
# LCOV 1.x (Ubuntu 22.04): 列顺序为 Hit, Total, Coverage%
|
|
72
|
+
# LCOV 2.0 (Ubuntu 24.04+): 列顺序为 Coverage%, Total, Hit
|
|
73
|
+
# 优先匹配LCOV 2.0格式,失败则回退LCOV 1.x格式
|
|
74
|
+
lcov2_cov_line = r"Lines:</td\>\n.*headerCovTableEntry(Lo|Hi|Med)\"\>([0-9.]+).*%.*\n.*headerCovTableEntry\"\>([0-9]+).*\n.*headerCovTableEntry\"\>([0-9]+)"
|
|
75
|
+
lcov1_cov_line = r"Lines:</td\>\n.*headerCovTableEntry\"\>([0-9]+).*\n.*headerCovTableEntry\"\>([0-9]+).*\n.*headerCovTableEntry(Lo|Hi|Med)\"\>([0-9.]+).*%"
|
|
76
|
+
matches = re.search(lcov2_cov_line, content)
|
|
77
|
+
if matches:
|
|
78
|
+
line_level = matches.group(1)
|
|
79
|
+
line_cov = float(matches.group(2))
|
|
80
|
+
line_total = int(matches.group(3))
|
|
81
|
+
line_hit = int(matches.group(4))
|
|
82
|
+
else:
|
|
83
|
+
matches = re.search(lcov1_cov_line, content)
|
|
84
|
+
if matches is None:
|
|
85
|
+
raise errors.LiteBmcException(f"Read line coverage data from {index_file} failed")
|
|
86
|
+
line_hit = int(matches.group(1))
|
|
87
|
+
line_total = int(matches.group(2))
|
|
88
|
+
line_level = matches.group(3)
|
|
89
|
+
line_cov = float(matches.group(4))
|
|
76
90
|
log.info("Coverage info:")
|
|
77
91
|
if line_level == "Hi":
|
|
78
92
|
log.success(f"Line: hit %-10d total %-10d coverage %.02f %% (High)" % (line_hit, line_total, line_cov))
|
|
@@ -80,13 +94,23 @@ class TestComponent():
|
|
|
80
94
|
log.warn(f"Line: hit %-10d total %-10d coverage %.02f %% (Medium)" % (line_hit, line_total, line_cov))
|
|
81
95
|
elif line_level == "Lo":
|
|
82
96
|
log.warn(f"Line: hit %-10d total %-10d coverage %.02f %% (Low!!!)" % (line_hit, line_total, line_cov))
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
|
|
98
|
+
lcov2_cov_func = r"Functions:</td\>\n.*headerCovTableEntry(Lo|Hi|Med)\"\>([0-9.]+).*%.*\n.*headerCovTableEntry\"\>([0-9]+).*\n.*headerCovTableEntry\"\>([0-9]+)"
|
|
99
|
+
lcov1_cov_func = r"Functions:</td\>\n.*headerCovTableEntry\"\>([0-9]+).*\n.*headerCovTableEntry\"\>([0-9]+).*\n.*headerCovTableEntry(Lo|Hi|Med)\"\>([0-9.]+).*%"
|
|
100
|
+
matches = re.search(lcov2_cov_func, content)
|
|
101
|
+
if matches:
|
|
102
|
+
func_level = matches.group(1)
|
|
103
|
+
func_cov = float(matches.group(2))
|
|
104
|
+
func_total = int(matches.group(3))
|
|
105
|
+
func_hit = int(matches.group(4))
|
|
106
|
+
else:
|
|
107
|
+
matches = re.search(lcov1_cov_func, content)
|
|
108
|
+
if matches is None:
|
|
109
|
+
raise errors.LiteBmcException(f"Read function coverage data from {index_file} failed")
|
|
110
|
+
func_hit = int(matches.group(1))
|
|
111
|
+
func_total = int(matches.group(2))
|
|
112
|
+
func_level = matches.group(3)
|
|
113
|
+
func_cov = float(matches.group(4))
|
|
90
114
|
if func_level == "Hi":
|
|
91
115
|
log.success(f"Function: hit %-10d total %-10d coverage %.02f %% (High)" % (func_hit, func_total, func_cov))
|
|
92
116
|
elif func_level == "Med":
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""下载缓存模块
|
|
2
|
+
|
|
3
|
+
提供共享下载缓存,避免重复下载相同的文件。
|
|
4
|
+
缓存文件以 sha256 命名存储在 ~/.cache/litebmc/download/ 目录下,
|
|
5
|
+
支持多进程并发安全(临时文件 + 原子重命名模式)。
|
|
6
|
+
"""
|
|
7
|
+
import os
|
|
8
|
+
import time
|
|
9
|
+
import shutil
|
|
10
|
+
import requests
|
|
11
|
+
|
|
12
|
+
from lbkit.misc import DOWNLOAD_CACHE_DIR
|
|
13
|
+
from lbkit.tools import Tools
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_cache_dir():
|
|
17
|
+
"""获取缓存目录路径。
|
|
18
|
+
|
|
19
|
+
解析优先级:
|
|
20
|
+
1. LBKIT_DOWNLOAD_CACHE 环境变量(设为空字符串则禁用缓存)
|
|
21
|
+
2. 默认路径 ~/.cache/litebmc/download/
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
str | None: 缓存目录路径,禁用时返回 None
|
|
25
|
+
"""
|
|
26
|
+
env = os.environ.get("LBKIT_DOWNLOAD_CACHE")
|
|
27
|
+
if env is not None:
|
|
28
|
+
if env == "":
|
|
29
|
+
return None
|
|
30
|
+
cache_dir = env
|
|
31
|
+
else:
|
|
32
|
+
cache_dir = DOWNLOAD_CACHE_DIR
|
|
33
|
+
try:
|
|
34
|
+
os.makedirs(cache_dir, exist_ok=True)
|
|
35
|
+
return cache_dir
|
|
36
|
+
except OSError:
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def cache_lookup(cache_dir, sha256):
|
|
41
|
+
"""在缓存中查找文件。
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
cache_dir: 缓存目录路径
|
|
45
|
+
sha256: 期望的文件 sha256 值
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
str | None: 缓存文件路径,未命中返回 None
|
|
49
|
+
"""
|
|
50
|
+
cache_file = os.path.join(cache_dir, sha256)
|
|
51
|
+
if not os.path.isfile(cache_file):
|
|
52
|
+
return None
|
|
53
|
+
calc_sha = Tools.file_digest_sha256(cache_file)
|
|
54
|
+
if calc_sha != sha256:
|
|
55
|
+
return None
|
|
56
|
+
return cache_file
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def cache_download_and_store(cache_dir, url, sha256, verify=True):
|
|
60
|
+
"""下载文件并存入缓存。
|
|
61
|
+
|
|
62
|
+
下载到临时文件,校验 sha256 后原子重命名为 {sha256}。
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
cache_dir: 缓存目录路径
|
|
66
|
+
url: 下载地址
|
|
67
|
+
sha256: 期望的 sha256 值
|
|
68
|
+
verify: SSL 证书校验开关
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
str: 缓存文件路径
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
Exception: 下载失败或 sha256 不匹配
|
|
75
|
+
"""
|
|
76
|
+
os.makedirs(cache_dir, exist_ok=True)
|
|
77
|
+
tmp_path = os.path.join(cache_dir, f".tmp_{os.getpid()}_{time.monotonic_ns()}")
|
|
78
|
+
try:
|
|
79
|
+
req = requests.get(url, stream=True, verify=verify, timeout=30)
|
|
80
|
+
req.raise_for_status()
|
|
81
|
+
total_size = int(req.headers.get('content-length', 0))
|
|
82
|
+
total_down = 0
|
|
83
|
+
last = time.time()
|
|
84
|
+
with open(tmp_path, 'wb') as fp:
|
|
85
|
+
for chunk in req.iter_content(chunk_size=16384):
|
|
86
|
+
if chunk:
|
|
87
|
+
fp.write(chunk)
|
|
88
|
+
total_down += len(chunk)
|
|
89
|
+
now = time.time()
|
|
90
|
+
if now - last > 30:
|
|
91
|
+
print(f"Downloading to cache, {total_down} / {total_size}")
|
|
92
|
+
last = now
|
|
93
|
+
calc_sha = Tools.file_digest_sha256(tmp_path)
|
|
94
|
+
if sha256 != "any" and calc_sha != sha256:
|
|
95
|
+
raise Exception(f"Cache download sha256 mismatch, need: {sha256}, get: {calc_sha}")
|
|
96
|
+
cache_file = os.path.join(cache_dir, sha256)
|
|
97
|
+
os.rename(tmp_path, cache_file)
|
|
98
|
+
return cache_file
|
|
99
|
+
except Exception:
|
|
100
|
+
if os.path.isfile(tmp_path):
|
|
101
|
+
os.unlink(tmp_path)
|
|
102
|
+
raise
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def cache_copy_to_dst(cache_file, dst):
|
|
106
|
+
"""从缓存复制文件到目标路径。
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
cache_file: 缓存文件路径
|
|
110
|
+
dst: 目标文件路径
|
|
111
|
+
"""
|
|
112
|
+
shutil.copyfile(cache_file, dst)
|
|
@@ -13,6 +13,7 @@ from jsonschema import validate, ValidationError
|
|
|
13
13
|
from lbkit.errors import PackageConfigException, HttpRequestException
|
|
14
14
|
|
|
15
15
|
LOG_DIR = os.path.join(Path.home(), ".cache", "lbkit", "log")
|
|
16
|
+
DOWNLOAD_CACHE_DIR = os.path.join(Path.home(), ".cache", "litebmc", "download")
|
|
16
17
|
TARGETS_DIR = "/usr/share/litebmc/targets"
|
|
17
18
|
|
|
18
19
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""环境准备"""
|
|
2
2
|
import os
|
|
3
|
-
import tempfile
|
|
4
3
|
from lbkit.tasks.config import Config
|
|
5
4
|
from lbkit.utils.images.emmc import MakeImage as MekeEmmcImage
|
|
6
5
|
from lbkit.tasks.image_maker.make_image import TaskMakeImage
|
|
6
|
+
from lbkit.utils.fakeroot import Fakeroot
|
|
7
7
|
|
|
8
8
|
src_cwd = os.path.split(os.path.realpath(__file__))[0]
|
|
9
9
|
|
|
@@ -17,7 +17,6 @@ class TaskMakeQemuImage(TaskMakeImage):
|
|
|
17
17
|
self.chip_model = chip_model
|
|
18
18
|
self.uboot = self.config.get_product_config("flash/uboot")
|
|
19
19
|
self.kernel = self.config.get_product_config("flash/kernel")
|
|
20
|
-
self.rootfs = self.config.rootfs_img
|
|
21
20
|
|
|
22
21
|
@staticmethod
|
|
23
22
|
def _trans_to_blk_1m(cfg: str):
|
|
@@ -37,26 +36,38 @@ class TaskMakeQemuImage(TaskMakeImage):
|
|
|
37
36
|
|
|
38
37
|
def run(self):
|
|
39
38
|
"""任务入口"""
|
|
40
|
-
"""检查manifest文件是否满足schema格式描述"""
|
|
41
39
|
os.chdir(self.config.output_path)
|
|
40
|
+
mnt_path = self.config.mnt_path
|
|
41
|
+
# 加载task_build_rootfs保存的fakeroot状态,继承权限配置
|
|
42
|
+
fakeroot_file = os.path.join(self.config.temp_path, "make_rootfs", "fakeroot.db")
|
|
43
|
+
fakeroot = Fakeroot(fakeroot_file)
|
|
44
|
+
fakeroot.start()
|
|
45
|
+
try:
|
|
46
|
+
self.config.fakeroot = fakeroot
|
|
47
|
+
# 复制内核文件到boot/Image
|
|
48
|
+
cmd = f"cp {self.kernel} {mnt_path}/boot/Image"
|
|
49
|
+
self.exec(cmd)
|
|
50
|
+
cmd = f"chown 0:0 {mnt_path}/boot/Image"
|
|
51
|
+
self.exec(cmd)
|
|
52
|
+
# 重新生成rootfs镜像
|
|
53
|
+
if os.path.exists(self.config.rootfs_img):
|
|
54
|
+
os.unlink(self.config.rootfs_img)
|
|
55
|
+
rootfs_size = self.config.get_product_config("rootfs/size")
|
|
56
|
+
size_mb = int(self._trans_to_blk_1m(rootfs_size)) if rootfs_size else 1024
|
|
57
|
+
cmd = f'mkfs.ext4 -d {mnt_path} -r 1 -N 0 -m 5 -L "rootfs" -O ^64bit {self.config.rootfs_img} "{size_mb}M"'
|
|
58
|
+
self.exec(cmd)
|
|
59
|
+
finally:
|
|
60
|
+
self.config.fakeroot = None
|
|
61
|
+
fakeroot.stop()
|
|
42
62
|
|
|
43
|
-
|
|
63
|
+
# 制作eMMC镜像
|
|
64
|
+
mk = MekeEmmcImage()
|
|
44
65
|
rootfs_size = self.config.get_product_config("rootfs/size")
|
|
45
66
|
if rootfs_size:
|
|
46
67
|
mk.rootfs_blk_1m = self._trans_to_blk_1m(rootfs_size)
|
|
47
68
|
emmc_size = self.config.get_product_config("flash/size")
|
|
48
69
|
if emmc_size:
|
|
49
70
|
mk.size_1m = self._trans_to_blk_1m(emmc_size)
|
|
50
|
-
tmpdir = tempfile.TemporaryDirectory()
|
|
51
|
-
cmd = f"fuse2fs {self.rootfs} {tmpdir.name} -o fakeroot"
|
|
52
|
-
self.exec(cmd)
|
|
53
|
-
# 复制内核文件到boot/extlinux/Image
|
|
54
|
-
cmd = f"cp {self.kernel} {tmpdir.name}/boot/Image"
|
|
55
|
-
self.exec(cmd)
|
|
56
|
-
cmd = f"chown 0:0 {tmpdir.name}/boot/Image"
|
|
57
|
-
self.exec(cmd)
|
|
58
|
-
cmd = f"umount {tmpdir.name}"
|
|
59
|
-
self.exec(cmd)
|
|
60
71
|
mk.run(self.config.rootfs_img, "qemu.img")
|
|
61
72
|
cmd = 'cp /usr/share/litebmc/qemu.conf qemu.conf'
|
|
62
73
|
self.exec(cmd)
|
|
@@ -26,10 +26,16 @@ class Task(Process):
|
|
|
26
26
|
self.log.info("install...........")
|
|
27
27
|
|
|
28
28
|
def exec(self, cmd: str, verbose=False, ignore_error = False, sensitive=False, log_prefix="", **kwargs):
|
|
29
|
+
fakeroot = getattr(self.config, 'fakeroot', None)
|
|
30
|
+
if fakeroot and fakeroot.active:
|
|
31
|
+
kwargs["extra_env"] = fakeroot.env
|
|
29
32
|
kwargs["uptrace"] = kwargs.get("uptrace", 0) + 1
|
|
30
33
|
return self.tools.exec(cmd, verbose, ignore_error, sensitive, log_prefix, **kwargs)
|
|
31
34
|
|
|
32
35
|
def pipe(self, cmds: list[str], ignore_error=False, out_file = None, **kwargs):
|
|
36
|
+
fakeroot = getattr(self.config, 'fakeroot', None)
|
|
37
|
+
if fakeroot and fakeroot.active:
|
|
38
|
+
kwargs["extra_env"] = fakeroot.env
|
|
33
39
|
kwargs["uptrace"] = kwargs.get("uptrace", 0) + 1
|
|
34
40
|
return self.tools.pipe(cmds, ignore_error, out_file, **kwargs)
|
|
35
41
|
|
|
@@ -43,20 +43,15 @@ class TaskClass(Task):
|
|
|
43
43
|
|
|
44
44
|
def deploy(self, graph_file):
|
|
45
45
|
with open(graph_file, "r") as fp:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
continue
|
|
56
|
-
id = pkg.get("package_id", "")
|
|
57
|
-
cmd = f"conan cache path {ref}:{id}"
|
|
58
|
-
package_folder = self.tools.run(cmd).stdout.strip()
|
|
59
|
-
self.config.conan_install.append(package_folder)
|
|
46
|
+
graph = json.load(fp)
|
|
47
|
+
nodes = graph.get("graph", {}).get("nodes", {})
|
|
48
|
+
for id, info in nodes.items():
|
|
49
|
+
context = info.get("context")
|
|
50
|
+
if context != "host":
|
|
51
|
+
continue
|
|
52
|
+
package_folder = info.get("package_folder", "")
|
|
53
|
+
if package_folder:
|
|
54
|
+
self.config.conan_install.append(package_folder)
|
|
60
55
|
|
|
61
56
|
def build_rootfs(self):
|
|
62
57
|
"""构建产品rootfs包"""
|
|
@@ -113,8 +108,11 @@ class TaskClass(Task):
|
|
|
113
108
|
bcp.build()
|
|
114
109
|
|
|
115
110
|
self.exec(f"sed -i 's@rootfs_df190c/0.0.1#.*\"@rootfs_df190c/0.0.1\"@g' {lockfile}")
|
|
111
|
+
# 用conan install获取所有依赖的package_folder信息,避免逐个调用conan cache path
|
|
112
|
+
graphfile = os.path.join(self.config.temp_path, "graph.info")
|
|
113
|
+
self.pipe([f"conan install . {base_cmd} --lockfile={lockfile} -f json"], out_file=graphfile)
|
|
116
114
|
# 部署应用到self.config.conan_install
|
|
117
|
-
self.deploy(
|
|
115
|
+
self.deploy(graphfile)
|
|
118
116
|
|
|
119
117
|
def run(self):
|
|
120
118
|
"""任务入口"""
|