Fix ARM64 musl node download discovery

This commit is contained in:
mm644706215
2026-03-21 11:54:20 +08:00
parent f3ce598550
commit 46b0b0f571
7 changed files with 162 additions and 17 deletions

View File

@@ -53,13 +53,14 @@ NODE_BIN="${NODE_BASE}/bin/node"
NPM_BIN="${NODE_BASE}/bin/npm"
PNPM_BIN="${OC_GLOBAL}/bin/pnpm"
# Node.js 官方镜像 + musl 非官方构建
# Node.js 官方镜像 + musl 非官方构建
# Node.js 下载源
OPENCLAW_GITHUB_REPO="${OPENCLAW_GITHUB_REPO:-hotwa/luci-app-openclaw}"
NODE_MIRROR="${NODE_MIRROR:-https://nodejs.org/dist}"
NODE_MIRROR_CN="https://npmmirror.com/mirrors/node"
NODE_MUSL_MIRROR="https://unofficial-builds.nodejs.org/download/release"
# 项目自托管 ARM64 musl Node.js (unofficial-builds 仅提供 x64 musl)
NODE_SELF_HOST="https://github.com/10000ge10000/luci-app-openclaw/releases/download/node-bins"
NODE_SELF_HOST="${NODE_SELF_HOST:-https://github.com/${OPENCLAW_GITHUB_REPO}/releases/download/node-bins}"
NODE_RELEASE_API="${NODE_RELEASE_API:-https://api.github.com/repos/${OPENCLAW_GITHUB_REPO}/releases/tags/node-bins}"
NODE_RELEASE_PAGE="${NODE_RELEASE_PAGE:-https://github.com/${OPENCLAW_GITHUB_REPO}/releases/tag/node-bins}"
export PATH="${NODE_BASE}/bin:${OC_GLOBAL}/bin:$PATH"
export NODE_ICU_DATA="${NODE_BASE}/share/icu"
@@ -68,6 +69,48 @@ log_info() { echo " [✓] $1"; }
log_warn() { echo " [!] $1"; }
log_error() { echo " [✗] $1"; }
download_url_to_file() {
local url="$1"
local output="$2"
curl -fSL --connect-timeout 15 --max-time 300 -o "$output" "$url" 2>/dev/null || \
wget -q --timeout=15 -O "$output" "$url" 2>/dev/null
}
resolve_arm64_musl_node_url() {
local node_ver="$1"
local release_json="/tmp/openclaw-node-bins-release.json"
local asset_url=""
echo " 正在从 ${NODE_RELEASE_API} 获取 ARM64 musl 版本列表..." >&2
if ! download_url_to_file "$NODE_RELEASE_API" "$release_json"; then
rm -f "$release_json"
log_error "无法获取 ARM64 musl Node.js 发布元数据" >&2
echo " 仓库: ${OPENCLAW_GITHUB_REPO}" >&2
echo " 最低要求: v${node_ver}" >&2
echo " Release API: ${NODE_RELEASE_API}" >&2
echo " Release 页面: ${NODE_RELEASE_PAGE}" >&2
echo " 请先发布 node-bins 中满足要求的 ARM64 musl 资产,或通过环境变量覆盖下载源" >&2
return 1
fi
asset_url=$(oc_select_node_release_asset_url "$release_json" "linux-arm64" "$node_ver" || true)
rm -f "$release_json"
if [ -n "$asset_url" ]; then
printf '%s\n' "$asset_url"
return 0
fi
log_error "未找到兼容的 ARM64 musl Node.js 资产" >&2
echo " 仓库: ${OPENCLAW_GITHUB_REPO}" >&2
echo " 最低要求: v${node_ver}" >&2
echo " Release API: ${NODE_RELEASE_API}" >&2
echo " Release 页面: ${NODE_RELEASE_PAGE}" >&2
echo " 请先发布 node-bins 中满足要求的 ARM64 musl 资产,或通过环境变量覆盖下载源" >&2
return 1
}
# 安全创建目录 (会在 _oc_fix_opt 修复 /opt 后使用标准路径)
ensure_mkdir() {
local target="$1"
@@ -169,17 +212,16 @@ download_node() {
local mirror_list=""
local musl_tarball="node-v${node_ver}-${node_arch}-musl.tar.xz"
local glibc_tarball="node-v${node_ver}-${node_arch}.tar.xz"
local arm64_musl_url=""
if [ "$libc_type" = "musl" ]; then
echo ""
echo "=== 下载 Node.js v${node_ver} (${node_arch}, musl libc) ==="
if [ "$node_arch" = "linux-arm64" ]; then
# ARM64 musl: unofficial-builds 不提供,从项目自托管下载
# 1) 项目自托管 ARM64 musl 构建 (当前版本)
mirror_list="${NODE_SELF_HOST}/${musl_tarball}"
# 2) unofficial-builds (留作将来可能支持)
mirror_list="$mirror_list ${NODE_MUSL_MIRROR}/v${node_ver}/${musl_tarball}"
# ARM64 musl: 从当前维护仓库的 node-bins release 动态选择兼容资产
arm64_musl_url=$(resolve_arm64_musl_node_url "$node_ver") || exit 1
mirror_list="${arm64_musl_url}"
else
# x64 musl: unofficial-builds 提供
# 1) unofficial-builds

View File

@@ -66,3 +66,53 @@ oc_read_node_version() {
version=$("$node_bin" --version 2>/dev/null) || return 1
oc_normalize_node_version "$version"
}
oc_select_node_release_asset_url() {
local json_file="${1:-}"
local node_arch="${2:-}"
local min_version="${3:-}"
local asset_regex=""
local urls=""
local best_url=""
local best_version=""
local url=""
local asset_name=""
local asset_version=""
[ -n "$json_file" ] || return 1
[ -f "$json_file" ] || return 1
oc_normalize_node_version "$min_version" >/dev/null || return 1
case "$node_arch" in
linux-arm64|linux-x64) ;;
*) return 1 ;;
esac
asset_regex="node-v[0-9][0-9.]*-${node_arch}-musl\\.tar\\.xz"
urls=$(
tr -d '\r' < "$json_file" | \
grep -o "\"browser_download_url\"[[:space:]]*:[[:space:]]*\"[^\"]*${asset_regex}\"" | \
sed 's/^"browser_download_url"[[:space:]]*:[[:space:]]*"//; s/"$//'
) || true
[ -n "$urls" ] || return 1
while IFS= read -r url; do
[ -n "$url" ] || continue
asset_name="${url##*/}"
asset_version=$(printf '%s\n' "$asset_name" | sed -n "s/^node-v\\([0-9][0-9.]*\\)-${node_arch}-musl\\.tar\\.xz$/\\1/p")
asset_version=$(oc_normalize_node_version "$asset_version" 2>/dev/null || true)
[ -n "$asset_version" ] || continue
if oc_node_version_ge "$asset_version" "$min_version"; then
if [ -z "$best_version" ] || oc_node_version_ge "$asset_version" "$best_version"; then
best_version="$asset_version"
best_url="$url"
fi
fi
done <<EOF
$urls
EOF
[ -n "$best_url" ] || return 1
printf '%s\n' "$best_url"
}