feat: 实现 APM addons 层功能并添加相关工具

新增 APM addons 层功能,允许在 base 环境上叠加额外环境层
添加 amber-pm-addons-maker 工具用于创建 addons 包
修改 amber-pm-convert 支持 --addons 参数
更新相关文档说明 addons 层功能
This commit is contained in:
2026-04-24 21:14:46 +08:00
parent 8c1137db06
commit f55dcc023d
7 changed files with 725 additions and 12 deletions
+87 -4
View File
@@ -92,28 +92,100 @@ apm_exec(){
# ===============================
local lowerdirs=()
local env_layers=()
local addon_envs=()
local processed_addon_pkgs=()
local current_dir="${PATH_PREFIX}/var/lib/apm/${coredir}"
local next_info_file=""
local APM_RUN_EXEC=/var/lib/apm/apm/files/ace-run
# ===============================
# 递归读取 info / info_env
# 辅助函数:解析并添加某个包的 addons
# ===============================
_resolve_addons() {
local pkgname="$1"
# 去重检查:每个包的 addons 只处理一次
for processed in "${processed_addon_pkgs[@]}"; do
[[ "$processed" == "$pkgname" ]] && return
done
processed_addon_pkgs+=("$pkgname")
local pkg_dir="${PATH_PREFIX}/var/lib/apm/${pkgname}"
local all_addons=()
# 先读取 info_layer_addons.d 目录(.d 配置优先级更高)
if [[ -d "${pkg_dir}/info_layer_addons.d" ]]; then
local addon_file
for addon_file in $(ls -1 "${pkg_dir}/info_layer_addons.d" 2>/dev/null | sort); do
local addon_name="${addon_file#*-}"
[[ -z "$addon_name" ]] && continue
all_addons+=("$addon_name")
done
fi
# 再读取 info_layer_addons 主文件
if [[ -f "${pkg_dir}/info_layer_addons" ]]; then
local addon_name
while IFS= read -r addon_name; do
[[ -z "$addon_name" ]] && continue
all_addons+=("$addon_name")
done < "${pkg_dir}/info_layer_addons"
fi
local addon
for addon in "${all_addons[@]}"; do
# 在 lowerdirs 中去重
local dup=false
local existing
for existing in "${lowerdirs[@]}"; do
if [[ "$existing" == "${PATH_PREFIX}/var/lib/apm/${addon}/files/ace-env" ]] || \
[[ "$existing" == "${PATH_PREFIX}/var/lib/apm/${addon}/files/core" ]]; then
dup=true
break
fi
done
[[ "$dup" == true ]] && continue
if [[ -d "${PATH_PREFIX}/var/lib/apm/${addon}/files/ace-env" ]]; then
lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${addon}/files/ace-env")
elif [[ -d "${PATH_PREFIX}/var/lib/apm/${addon}/files/core" ]]; then
lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${addon}/files/core")
else
log.warn "Addon layer not found: $addon"
continue
fi
if [[ -f "${PATH_PREFIX}/var/lib/apm/${addon}/info_env" ]]; then
addon_envs+=("${PATH_PREFIX}/var/lib/apm/${addon}/info_env")
fi
done
}
# ===============================
# 递归读取 info / info_env / addons
# ===============================
while : ; do
next_info_file="${current_dir}/info"
# 记录 info_env(底层优先)
# 记录 info_env
if [[ -f "${current_dir}/info_env" ]]; then
env_layers+=("${current_dir}/info_env")
fi
# 没有 info 停止
[[ ! -f "$next_info_file" ]] && break
# 没有 info 也处理 addons(最底层 base 也可以有 addons),然后停止
if [[ ! -f "$next_info_file" ]]; then
local pkgname
pkgname="$(basename "$current_dir")"
_resolve_addons "$pkgname"
break
fi
# 读取依赖层
while IFS= read -r basedir; do
[[ -z "$basedir" ]] && continue
# 先处理该 base 的 addonsaddons 在 base 之上)
_resolve_addons "$basedir"
if [[ -d "${PATH_PREFIX}/var/lib/apm/${basedir}/files/ace-env" ]]; then
lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${basedir}/files/ace-env")
elif [[ -d "${PATH_PREFIX}/var/lib/apm/${basedir}/files/core" ]]; then
@@ -168,6 +240,17 @@ apm_exec(){
fi
fi
# ===============================
# 追加 addon envs(在 base env 之后,override env 之前)
# 反向追加以确保层级高的 addon env 后加载(优先级更高)
# ===============================
if [[ ${#addon_envs[@]} -gt 0 ]]; then
local i
for ((i=${#addon_envs[@]}-1; i>=0; i--)); do
env_layers+=("${addon_envs[i]}")
done
fi
# ===============================
# 检查 lowerdir
# ===============================