Files

75 lines
2.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# build_all.sh —— BIOFLOW 8 环境镜像构建脚本(镜像标准形态, 零硬编码)
# 方法: docs/bioflow_image_build_playbook.md
# 用法: build_all.sh <image|all> [pack-dir]
# pack-dir: 存放 conda-pack 产物 <env>.tar.gz 的目录;
# 未传参时取环境变量 BIOFLOW_PACK_DIR, 仍未设置则报错退出(零硬编码)。
set -euo pipefail
TARGET="${1:-all}"
PACK_DIR="${2:-${BIOFLOW_PACK_DIR:-}}"
[[ -n "$PACK_DIR" ]] || { echo "Usage: $0 <all|gf|...> <pack-dir> (or set BIOFLOW_PACK_DIR)" >&2; exit 2; }
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
KERNEL_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# 镜像名 -> 源环境 tar(conda-pack 产物命名约定: <env>.tar.gz)
IMAGES=(gf gfpy rnaseq rnaR wgs interproscan pan rde)
declare -A ENV_TAR=(
[gf]=test4py311
[gfpy]=gfpy312
[rnaseq]=rnaseq
[rnaR]=rnaR
[wgs]=ASAW
[interproscan]=interproscanpy311
[pan]=panfamily
[rde]=r_de_analysis
)
# 宿主外部软链修复 extras(可选, pack-dir 下同名 *.tar.gz 存在即传入 --build-arg EXTRAS_TAR)
declare -A EXTRAS=(
[interproscan]=interproscan-tool
[rnaseq]=star-extras
)
build_one() {
local img="$1"
local env="${ENV_TAR[$img]}"
local tar_file="$PACK_DIR/${env}.tar.gz"
[[ -f "$tar_file" ]] || { echo "[FAIL] missing pack artifact: $tar_file" >&2; return 2; }
# 构建上下文: 临时 stage 目录(kernel-src 只读拷贝 + tar 软链, 避免 ADD 大文件跨文件系统复制)
local stage
# stage 建在 pack-dir 下(同文件系统): tar 硬链接 + 内核源码 rsync 拷贝,
# 规避 BuildKit 上下文外软链解析失败的问题; 源码仅 ~22M, 拷贝开销可忽略
stage="$(mktemp -d "$PACK_DIR/.build.XXXXXX")"
ln "$tar_file" "$stage/${env}.tar.gz"
local extra_arg=()
if [[ -n "${EXTRAS[$img]:-}" && -f "$PACK_DIR/${EXTRAS[$img]}.tar.gz" ]]; then
ln "$PACK_DIR/${EXTRAS[$img]}.tar.gz" "$stage/${EXTRAS[$img]}.tar.gz"
extra_arg=(--build-arg "EXTRAS_TAR=${EXTRAS[$img]}.tar.gz")
fi
mkdir -p "$stage/kernel-src"
# 排除 __pycache__ 与 dev 历史备份(.bak*/.orig, 含旧版硬编码, 绝不入镜像)
rsync -a --exclude '__pycache__' --exclude '*.bak*' --exclude '*.orig' \
"$KERNEL_ROOT/" "$stage/kernel-src/"
echo "[BUILD] bioflow-$img ($env) stage=$stage"
docker build \
--build-arg BASE_IMAGE="${BIOFLOW_BASE_IMAGE:-ubuntu:24.04}" \
--build-arg ENV_TAR="${env}.tar.gz" \
"${extra_arg[@]}" \
-f "$SCRIPT_DIR/Dockerfile.bioflow-$img" \
-t "bioflow-${img,,}:dev" \
"$stage"
rm -rf "$stage"
echo "[OK] bioflow-$img"
}
if [[ "$TARGET" == "all" ]]; then
for img in "${IMAGES[@]}"; do
build_one "$img"
done
elif [[ -n "${ENV_TAR[$TARGET]:-}" ]]; then
build_one "$TARGET"
else
echo "Usage: $0 <all|gf|gfpy|rnaseq|rnaR|wgs|interproscan|pan|rde> [pack-dir]" >&2
exit 2
fi