fix(bioflow): 内核树运行时挂载——非 gf 阶段镜像缺 cli 模块

- 8 个阶段镜像中仅 bioflow-gf 内置 /bioflow-kernel,其余 7 个
  (rnaseq/wgs/gfpy/rnar/rde/pan/interproscan) 执行时 No module named cli
- 服务端统一 -v kernel_dir:/bioflow-kernel:ro + -w /bioflow-kernel,
  全部镜像可用,免重建 7 个镜像
- config 新增 kernel_dir/container_kernel_dir(env 可覆盖)
- 337 用例全绿

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 23:22:06 +08:00
co-authored by Claude Fable 5
parent 2ee9af4bd0
commit 04fb306624
3 changed files with 30 additions and 0 deletions
+8
View File
@@ -35,6 +35,10 @@ class Settings(BaseSettings):
# ---- 阶段→镜像映射(A1 交付物,仓库内 bioflow_kernel/stage_image_map.json)----
image_map_path: str = "bioflow_kernel/stage_image_map.json"
# 内核树:运行时只读挂载进执行容器(-v kernel:/bioflow-kernel:ro + -w)
# 除 bioflow-gf 外其余镜像未内置内核,挂载后全部阶段镜像统一可用
kernel_dir: str = "bioflow_kernel"
container_kernel_dir: str = "/bioflow-kernel"
# ---- 数据与任务目录 ----
data_root: str = "bioflow_data" # 生信数据根(hmm/rag_db 等,只读挂载进容器)
@@ -125,6 +129,10 @@ class Settings(BaseSettings):
def data_root_abs(self) -> str:
return _resolve_root(self.data_root)
@property
def kernel_dir_abs(self) -> str:
return _resolve_root(self.kernel_dir)
@property
def jobs_dir_abs(self) -> str:
return _resolve_root(self.jobs_dir)
@@ -72,6 +72,8 @@ class KernelConfig:
cpu_allow: str = "4,8,16,32"
memory_allow: str = "16g,32g,64g"
extra_mounts: list[str] = field(default_factory=list) # 登记路径只读挂载(src==dst)
kernel_dir: str = "" # 内核树宿主路径(运行时挂载进容器)
container_kernel_dir: str = "/bioflow-kernel" # 容器内内核树路径
class Kernel:
@@ -145,6 +147,10 @@ class Kernel:
# 登记路径只读挂载(src==dst,容器内原路径直接可见;登记时已过黑名单)
for m in (extra_mounts or self.cfg.extra_mounts):
cmd += ["-v", f"{m}:{m}:ro"]
# 内核树运行时挂载(除 bioflow-gf 外其余镜像未内置内核,统一走挂载)
if self.cfg.kernel_dir:
cmd += ["-v", f"{self.cfg.kernel_dir}:{self.cfg.container_kernel_dir}:ro"]
cmd += ["-w", self.cfg.container_kernel_dir]
eff_cpu = cpu or str(params.get("cpu") or "")
eff_memory = memory or str(params.get("memory") or "")
cmd += ["--cpus", self._safe_cpu(eff_cpu or self.cfg.default_cpus)]
@@ -286,6 +292,8 @@ def _default_kernel_config() -> KernelConfig:
stage_timeout_sec=s.stage_timeout_sec,
log_tail_lines=s.log_tail_lines,
bba_env=s.bba_env,
kernel_dir=s.kernel_dir_abs,
container_kernel_dir=s.container_kernel_dir,
)
+14
View File
@@ -75,6 +75,20 @@ def test_build_command_extra_mounts(kernel, tmp_path):
assert f"{m}:{m}:ro" in cmd
def test_build_command_kernel_dir_mount(tmp_path):
"""内核树运行时挂载:-v kernel:/bioflow-kernel:ro + -w /bioflow-kernel。"""
from app.services.bioflow.kernel import Kernel, KernelConfig, ImageMap
cfg = KernelConfig(host_uid=1234, kernel_dir=str(tmp_path / "kernel"),
container_kernel_dir="/bioflow-kernel",
data_root=str(tmp_path / "data"))
img = ImageMap(images={"gf": {"docker_tag": "bioflow-gf"}},
stages={"identify": {"image": "gf", "module": "cli.run_identify"}})
k = Kernel(img, cfg)
cmd = k.build_command("identify", tmp_path / "in", tmp_path / "ws")
assert f"{tmp_path}/kernel:/bioflow-kernel:ro" in cmd
assert "-w" in cmd and "/bioflow-kernel" in cmd
def test_build_command_params(kernel, tmp_path):
cmd = kernel.build_command("identify", tmp_path / "in", tmp_path / "ws",
{"prefix": "Ft.SPL", "required_pfams": "PF03110",