mirror of
https://github.com/hotwa/luci-app-openclaw.git
synced 2026-03-31 04:52:33 +00:00
Support relocatable custom install roots
This commit is contained in:
42
.github/workflows/build-node-musl.yml
vendored
42
.github/workflows/build-node-musl.yml
vendored
@@ -62,6 +62,27 @@ jobs:
|
||||
echo "=== Tarball contents (first 20 entries) ==="
|
||||
tar tJf dist/*.tar.xz | head -20
|
||||
|
||||
- name: Verify relocatable tarball
|
||||
run: |
|
||||
docker run --rm --platform linux/arm64 \
|
||||
-v "$PWD/dist:/dist:ro" \
|
||||
alpine:3.21 sh -euxc '
|
||||
apk add --no-cache xz icu-data-full tar
|
||||
TARBALL=$(ls /dist/*.tar.xz | head -1)
|
||||
verify_prefix() {
|
||||
prefix="$1"
|
||||
rm -rf "$prefix"
|
||||
mkdir -p "$prefix"
|
||||
tar -xJf "$TARBALL" --strip-components=1 -C "$prefix"
|
||||
"$prefix/bin/node" --version
|
||||
exec_path=$("$prefix/bin/node" -e "process.stdout.write(process.execPath)")
|
||||
[ "$exec_path" = "$prefix/bin/node" ]
|
||||
NODE_ICU_DATA="$prefix/share/icu" "$prefix/bin/npm" --version >/dev/null
|
||||
}
|
||||
verify_prefix /opt/openclaw/node
|
||||
verify_prefix /tmp/custom-openclaw-root/openclaw/node
|
||||
'
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -115,6 +136,27 @@ jobs:
|
||||
echo "=== Tarball contents (first 20 entries) ==="
|
||||
tar tJf dist/*.tar.xz | head -20
|
||||
|
||||
- name: Verify relocatable tarball
|
||||
run: |
|
||||
docker run --rm --platform linux/arm64 \
|
||||
-v "$PWD/dist:/dist:ro" \
|
||||
alpine:3.21 sh -euxc '
|
||||
apk add --no-cache xz icu-data-full tar
|
||||
TARBALL=$(ls /dist/*.tar.xz | head -1)
|
||||
verify_prefix() {
|
||||
prefix="$1"
|
||||
rm -rf "$prefix"
|
||||
mkdir -p "$prefix"
|
||||
tar -xJf "$TARBALL" --strip-components=1 -C "$prefix"
|
||||
"$prefix/bin/node" --version
|
||||
exec_path=$("$prefix/bin/node" -e "process.stdout.write(process.execPath)")
|
||||
[ "$exec_path" = "$prefix/bin/node" ]
|
||||
NODE_ICU_DATA="$prefix/share/icu" "$prefix/bin/npm" --version >/dev/null
|
||||
}
|
||||
verify_prefix /opt/openclaw/node
|
||||
verify_prefix /tmp/custom-openclaw-root/openclaw/node
|
||||
'
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
||||
1
Makefile
1
Makefile
@@ -58,6 +58,7 @@ define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_BIN) ./root/usr/bin/openclaw-env $(1)/usr/bin/openclaw-env
|
||||
$(INSTALL_DIR) $(1)/usr/libexec
|
||||
$(INSTALL_BIN) ./root/usr/libexec/openclaw-paths.sh $(1)/usr/libexec/openclaw-paths.sh
|
||||
$(INSTALL_BIN) ./root/usr/libexec/openclaw-node.sh $(1)/usr/libexec/openclaw-node.sh
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
|
||||
$(INSTALL_DATA) ./luasrc/controller/openclaw.lua $(1)/usr/lib/lua/luci/controller/openclaw.lua
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/openclaw
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
set -e
|
||||
|
||||
. /usr/libexec/openclaw-paths.sh
|
||||
. /usr/libexec/openclaw-node.sh
|
||||
|
||||
# ── Node.js 版本策略 (双版本兼容) ──
|
||||
# ── Node.js 版本策略 ──
|
||||
# V2: 当前推荐版本,用于 OpenClaw v2026.3.11+ (要求 >= 22.16.0)
|
||||
# V1: 旧版兼容,用于 OpenClaw v2026.3.8 及更早版本
|
||||
# V1: 保留给显式指定旧版环境时使用,不再作为 V2 的自动回退
|
||||
NODE_VERSION_V2="22.16.0"
|
||||
NODE_VERSION_V1="22.15.1"
|
||||
# 默认使用 V2 版本 (可通过 NODE_VERSION 环境变量覆盖)
|
||||
@@ -148,23 +149,23 @@ download_node() {
|
||||
# 如果已存在且版本兼容, 跳过
|
||||
if [ -x "$NODE_BIN" ]; then
|
||||
local current_ver
|
||||
current_ver=$("$NODE_BIN" --version 2>/dev/null | sed 's/^v//')
|
||||
if [ "$current_ver" = "$node_ver" ]; then
|
||||
current_ver=$(oc_read_node_version "$NODE_BIN" || true)
|
||||
if [ -n "$current_ver" ] && [ "$current_ver" = "$node_ver" ]; then
|
||||
log_info "Node.js v${node_ver} 已安装, 跳过下载"
|
||||
return 0
|
||||
fi
|
||||
# ARM64 musl 使用 Alpine 打包,版本号可能不完全匹配
|
||||
# 只要主版本号相同即认为兼容 (如 22.15.1 vs 22.15.0)
|
||||
local cur_major=$(echo "$current_ver" | cut -d. -f1)
|
||||
local want_major=$(echo "$node_ver" | cut -d. -f1)
|
||||
if [ "$cur_major" = "$want_major" ]; then
|
||||
log_info "Node.js v${current_ver} 已安装 (兼容 v${node_ver}), 跳过下载"
|
||||
if [ -n "$current_ver" ] && oc_node_version_ge "$current_ver" "$node_ver"; then
|
||||
log_info "Node.js v${current_ver} 已安装 (满足 >= v${node_ver}), 跳过下载"
|
||||
return 0
|
||||
fi
|
||||
log_warn "当前 Node.js v${current_ver}, 将更新到 v${node_ver}"
|
||||
if [ -n "$current_ver" ]; then
|
||||
log_warn "当前 Node.js v${current_ver} 低于要求 v${node_ver}, 将更新"
|
||||
else
|
||||
log_warn "检测到现有 Node.js 文件但无法运行,将重新安装"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 构建下载 URL 列表 (按优先级排列,支持双版本回退) ──
|
||||
# ── 构建下载 URL 列表 (按优先级排列) ──
|
||||
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"
|
||||
@@ -179,11 +180,6 @@ download_node() {
|
||||
mirror_list="${NODE_SELF_HOST}/${musl_tarball}"
|
||||
# 2) unofficial-builds (留作将来可能支持)
|
||||
mirror_list="$mirror_list ${NODE_MUSL_MIRROR}/v${node_ver}/${musl_tarball}"
|
||||
# 3) 回退到 V1 版本 (兼容旧环境,仅当请求 V2 时)
|
||||
if [ "$node_ver" = "$NODE_VERSION_V2" ]; then
|
||||
local v1_tarball="node-v${NODE_VERSION_V1}-${node_arch}-musl.tar.xz"
|
||||
mirror_list="$mirror_list ${NODE_SELF_HOST}/${v1_tarball}"
|
||||
fi
|
||||
else
|
||||
# x64 musl: unofficial-builds 提供
|
||||
# 1) unofficial-builds
|
||||
@@ -262,14 +258,18 @@ download_node() {
|
||||
rm -f "$tmp_file"
|
||||
|
||||
# 验证
|
||||
if [ -x "$NODE_BIN" ]; then
|
||||
local installed_ver
|
||||
installed_ver=$("$NODE_BIN" --version 2>/dev/null || echo "unknown")
|
||||
local installed_ver
|
||||
installed_ver=$(oc_read_node_version "$NODE_BIN" || true)
|
||||
if [ -n "$installed_ver" ] && oc_node_version_ge "$installed_ver" "$node_ver"; then
|
||||
log_info "Node.js ${installed_ver} 安装成功"
|
||||
return 0
|
||||
fi
|
||||
if [ -n "$installed_ver" ]; then
|
||||
log_error "Node.js 版本过低: v${installed_ver} < v${node_ver}"
|
||||
else
|
||||
log_error "Node.js 安装验证失败"
|
||||
exit 1
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
install_pnpm() {
|
||||
@@ -410,9 +410,11 @@ init_openclaw() {
|
||||
|
||||
do_setup() {
|
||||
local node_ver="$NODE_VERSION"
|
||||
local installed_node_ver=""
|
||||
installed_node_ver=$(oc_read_node_version "$NODE_BIN" || true)
|
||||
|
||||
# 检查是否已安装
|
||||
if [ -x "$NODE_BIN" ] && [ -n "$(find_oc_entry)" ]; then
|
||||
if [ -n "$installed_node_ver" ] && [ -n "$(find_oc_entry)" ]; then
|
||||
local oc_ver=""
|
||||
local oc_entry="$(find_oc_entry)"
|
||||
local oc_pkg_dir="$(dirname "$oc_entry")"
|
||||
@@ -422,7 +424,7 @@ do_setup() {
|
||||
echo "║ ⚠️ OpenClaw 运行环境已安装,无需重复安装 ║"
|
||||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo " Node.js: $($NODE_BIN --version 2>/dev/null)"
|
||||
echo " Node.js: v${installed_node_ver}"
|
||||
[ -n "$oc_ver" ] && echo " OpenClaw: v${oc_ver}"
|
||||
echo ""
|
||||
echo " 如需升级,请使用: openclaw-env upgrade"
|
||||
@@ -465,8 +467,10 @@ do_check() {
|
||||
echo ""
|
||||
|
||||
# Node.js
|
||||
if [ -x "$NODE_BIN" ]; then
|
||||
echo " Node.js: $($NODE_BIN --version 2>/dev/null)"
|
||||
local installed_node_ver=""
|
||||
installed_node_ver=$(oc_read_node_version "$NODE_BIN" || true)
|
||||
if [ -n "$installed_node_ver" ]; then
|
||||
echo " Node.js: v${installed_node_ver}"
|
||||
else
|
||||
echo " Node.js: 未安装"
|
||||
fi
|
||||
@@ -511,7 +515,9 @@ do_upgrade() {
|
||||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
if [ ! -x "$NODE_BIN" ]; then
|
||||
local installed_node_ver=""
|
||||
installed_node_ver=$(oc_read_node_version "$NODE_BIN" || true)
|
||||
if [ -z "$installed_node_ver" ]; then
|
||||
log_error "Node.js 未安装, 请先运行: openclaw-env setup"
|
||||
exit 1
|
||||
fi
|
||||
@@ -526,7 +532,7 @@ do_upgrade() {
|
||||
current_ver=$("$NODE_BIN" -e "try{console.log(require('$oc_pkg_dir/package.json').version)}catch(e){}" 2>/dev/null) || true
|
||||
fi
|
||||
|
||||
echo " Node.js: $($NODE_BIN --version 2>/dev/null)"
|
||||
echo " Node.js: v${installed_node_ver}"
|
||||
[ -n "$current_ver" ] && echo " 当前版本: v${current_ver}"
|
||||
echo ""
|
||||
|
||||
@@ -643,7 +649,9 @@ do_setup_offline() {
|
||||
fi
|
||||
|
||||
# 检查是否已安装
|
||||
if [ -x "$NODE_BIN" ] && [ -n "$(find_oc_entry)" ]; then
|
||||
local installed_node_ver=""
|
||||
installed_node_ver=$(oc_read_node_version "$NODE_BIN" || true)
|
||||
if [ -n "$installed_node_ver" ] && [ -n "$(find_oc_entry)" ]; then
|
||||
log_warn "OpenClaw 运行环境已安装"
|
||||
log_warn "如需重新离线安装,请先卸载现有环境"
|
||||
exit 0
|
||||
@@ -680,8 +688,10 @@ do_setup_offline() {
|
||||
rm -rf "$tmp_extract"
|
||||
fi
|
||||
|
||||
if [ -x "$NODE_BIN" ]; then
|
||||
log_info "Node.js $($NODE_BIN --version 2>/dev/null) 安装成功"
|
||||
local offline_node_ver=""
|
||||
offline_node_ver=$(oc_read_node_version "$NODE_BIN" || true)
|
||||
if [ -n "$offline_node_ver" ]; then
|
||||
log_info "Node.js v${offline_node_ver} 安装成功"
|
||||
else
|
||||
log_error "Node.js 安装失败"
|
||||
exit 1
|
||||
|
||||
68
root/usr/libexec/openclaw-node.sh
Normal file
68
root/usr/libexec/openclaw-node.sh
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
# Shared OpenClaw Node.js runtime/version helpers.
|
||||
|
||||
oc_normalize_node_version() {
|
||||
local version="${1:-}"
|
||||
local old_ifs
|
||||
|
||||
[ -n "$version" ] || return 1
|
||||
case "$version" in
|
||||
v*) version="${version#v}" ;;
|
||||
esac
|
||||
case "$version" in
|
||||
''|*[!0-9.]*) return 1 ;;
|
||||
esac
|
||||
|
||||
old_ifs="$IFS"
|
||||
IFS=.
|
||||
set -- $version
|
||||
IFS="$old_ifs"
|
||||
|
||||
[ "$#" -eq 3 ] || return 1
|
||||
for part in "$1" "$2" "$3"; do
|
||||
case "$part" in
|
||||
''|*[!0-9]*) return 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
printf '%s.%s.%s\n' "$1" "$2" "$3"
|
||||
}
|
||||
|
||||
oc_node_version_ge() {
|
||||
local lhs rhs
|
||||
local old_ifs
|
||||
local lhs_major lhs_minor lhs_patch
|
||||
local rhs_major rhs_minor rhs_patch
|
||||
|
||||
lhs=$(oc_normalize_node_version "${1:-}") || return 1
|
||||
rhs=$(oc_normalize_node_version "${2:-}") || return 1
|
||||
|
||||
old_ifs="$IFS"
|
||||
IFS=.
|
||||
set -- $lhs
|
||||
lhs_major="$1"
|
||||
lhs_minor="$2"
|
||||
lhs_patch="$3"
|
||||
set -- $rhs
|
||||
rhs_major="$1"
|
||||
rhs_minor="$2"
|
||||
rhs_patch="$3"
|
||||
IFS="$old_ifs"
|
||||
|
||||
[ "$lhs_major" -gt "$rhs_major" ] && return 0
|
||||
[ "$lhs_major" -lt "$rhs_major" ] && return 1
|
||||
[ "$lhs_minor" -gt "$rhs_minor" ] && return 0
|
||||
[ "$lhs_minor" -lt "$rhs_minor" ] && return 1
|
||||
[ "$lhs_patch" -ge "$rhs_patch" ]
|
||||
}
|
||||
|
||||
oc_read_node_version() {
|
||||
local node_bin="${1:-}"
|
||||
local version
|
||||
|
||||
[ -n "$node_bin" ] || return 1
|
||||
[ -x "$node_bin" ] || return 1
|
||||
|
||||
version=$("$node_bin" --version 2>/dev/null) || return 1
|
||||
oc_normalize_node_version "$version"
|
||||
}
|
||||
@@ -12,14 +12,16 @@
|
||||
# 1. apk 模式: 使用 Alpine apk 安装 nodejs,版本受限于 Alpine 仓库
|
||||
# 2. cross 模式: 从 Node.js 官方下载 glibc 版本,转换为 musl
|
||||
# 使用 patchelf 修改 node 二进制的 ELF interpreter 和 rpath,
|
||||
# 使其直接使用打包的 musl 链接器和共享库,无需 LD_LIBRARY_PATH。
|
||||
# 使其使用系统 musl 动态链接器和相对 rpath,可从任意安装根目录直接运行。
|
||||
# 这样 process.execPath 返回正确的 node 路径,子进程 fork 也能正常工作。
|
||||
# 安装路径固定为 /opt/openclaw/node (与 openclaw-env 一致)。
|
||||
# ============================================================================
|
||||
set -e
|
||||
|
||||
INSTALL_PREFIX="/opt/openclaw/node"
|
||||
BUILD_MODE="${BUILD_MODE:-apk}"
|
||||
DEFAULT_VERIFY_PREFIX="/opt/openclaw/node"
|
||||
CUSTOM_VERIFY_PREFIX="/tmp/custom-openclaw-root/openclaw/node"
|
||||
SYSTEM_MUSL_LOADER="/lib/ld-musl-aarch64.so.1"
|
||||
RELATIVE_RPATH='$ORIGIN/../lib'
|
||||
|
||||
echo "=== Node.js ARM64 musl Build ==="
|
||||
echo " Target version: v${NODE_VER}"
|
||||
@@ -198,10 +200,10 @@ finalize_package() {
|
||||
|
||||
# 用 patchelf 修改 node 二进制
|
||||
echo "=== Patching ELF binary ==="
|
||||
patchelf --set-interpreter "${INSTALL_PREFIX}/lib/ld-musl-aarch64.so.1" "${PKG_DIR}/bin/node"
|
||||
patchelf --set-rpath "${INSTALL_PREFIX}/lib" "${PKG_DIR}/bin/node"
|
||||
echo " interpreter: ${INSTALL_PREFIX}/lib/ld-musl-aarch64.so.1"
|
||||
echo " rpath: ${INSTALL_PREFIX}/lib"
|
||||
patchelf --set-interpreter "/lib/ld-musl-aarch64.so.1" "${PKG_DIR}/bin/node"
|
||||
patchelf --set-rpath "$RELATIVE_RPATH" "${PKG_DIR}/bin/node"
|
||||
echo " interpreter: ${SYSTEM_MUSL_LOADER}"
|
||||
echo " rpath: ${RELATIVE_RPATH}"
|
||||
|
||||
# 创建 node wrapper 脚本
|
||||
cat > "${PKG_DIR}/bin/node-wrapper" << 'NODEWRAPPER'
|
||||
@@ -229,20 +231,27 @@ exec "${SELF_DIR}/node" "${SELF_DIR}/../lib/node_modules/npm/bin/npx-cli.js" "$@
|
||||
NPXWRAPPER
|
||||
chmod +x "${PKG_DIR}/bin/npm" "${PKG_DIR}/bin/npx"
|
||||
|
||||
# 验证
|
||||
echo "=== Verification ==="
|
||||
mkdir -p "${INSTALL_PREFIX}"
|
||||
cp -a "${PKG_DIR}"/* "${INSTALL_PREFIX}/"
|
||||
verify_prefix() {
|
||||
local prefix="$1"
|
||||
local label="$2"
|
||||
local exec_path=""
|
||||
|
||||
# 设置库路径并测试
|
||||
export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib"
|
||||
echo "=== Verification (${label}) ==="
|
||||
rm -rf "$prefix" 2>/dev/null || true
|
||||
mkdir -p "$prefix"
|
||||
cp -a "${PKG_DIR}"/* "${prefix}/"
|
||||
|
||||
"${INSTALL_PREFIX}/bin/node" --version
|
||||
"${INSTALL_PREFIX}/bin/node" -e "console.log('execPath:', process.execPath)"
|
||||
"${INSTALL_PREFIX}/bin/node" -e "console.log(process.arch, process.platform, process.versions.modules)"
|
||||
NODE_ICU_DATA="${INSTALL_PREFIX}/share/icu" "${INSTALL_PREFIX}/bin/npm" --version 2>/dev/null || echo "npm needs ICU data"
|
||||
"${prefix}/bin/node" --version
|
||||
exec_path=$("${prefix}/bin/node" -e "process.stdout.write(process.execPath)")
|
||||
[ "$exec_path" = "${prefix}/bin/node" ]
|
||||
"${prefix}/bin/node" -e "console.log(process.arch, process.platform, process.versions.modules)"
|
||||
NODE_ICU_DATA="${prefix}/share/icu" "${prefix}/bin/npm" --version >/dev/null
|
||||
|
||||
rm -rf "${INSTALL_PREFIX}"
|
||||
rm -rf "$prefix" 2>/dev/null || true
|
||||
}
|
||||
|
||||
verify_prefix "$DEFAULT_VERIFY_PREFIX" "default install root"
|
||||
verify_prefix "$CUSTOM_VERIFY_PREFIX" "custom install root"
|
||||
|
||||
# 打包
|
||||
echo "=== Creating tarball ==="
|
||||
|
||||
@@ -51,10 +51,20 @@ mkdir -p "$DATA_DIR/usr/bin"
|
||||
cp "$PKG_DIR/root/usr/bin/openclaw-env" "$DATA_DIR/usr/bin/"
|
||||
chmod +x "$DATA_DIR/usr/bin/openclaw-env"
|
||||
|
||||
# libexec helpers
|
||||
mkdir -p "$DATA_DIR/usr/libexec"
|
||||
cp "$PKG_DIR/root/usr/libexec/openclaw-paths.sh" "$DATA_DIR/usr/libexec/"
|
||||
cp "$PKG_DIR/root/usr/libexec/openclaw-node.sh" "$DATA_DIR/usr/libexec/"
|
||||
chmod +x "$DATA_DIR/usr/libexec/openclaw-paths.sh" "$DATA_DIR/usr/libexec/openclaw-node.sh"
|
||||
|
||||
# LuCI controller
|
||||
mkdir -p "$DATA_DIR/usr/lib/lua/luci/controller"
|
||||
cp "$PKG_DIR/luasrc/controller/openclaw.lua" "$DATA_DIR/usr/lib/lua/luci/controller/"
|
||||
|
||||
# Shared Lua helpers
|
||||
mkdir -p "$DATA_DIR/usr/lib/lua/openclaw"
|
||||
cp "$PKG_DIR/luasrc/openclaw/paths.lua" "$DATA_DIR/usr/lib/lua/openclaw/"
|
||||
|
||||
# LuCI CBI
|
||||
mkdir -p "$DATA_DIR/usr/lib/lua/luci/model/cbi/openclaw"
|
||||
cp "$PKG_DIR/luasrc/model/cbi/openclaw/"*.lua "$DATA_DIR/usr/lib/lua/luci/model/cbi/openclaw/"
|
||||
|
||||
@@ -54,10 +54,20 @@ install_files() {
|
||||
cp "$PKG_DIR/root/usr/bin/openclaw-env" "$dest/usr/bin/"
|
||||
chmod +x "$dest/usr/bin/openclaw-env"
|
||||
|
||||
# libexec helpers
|
||||
mkdir -p "$dest/usr/libexec"
|
||||
cp "$PKG_DIR/root/usr/libexec/openclaw-paths.sh" "$dest/usr/libexec/"
|
||||
cp "$PKG_DIR/root/usr/libexec/openclaw-node.sh" "$dest/usr/libexec/"
|
||||
chmod +x "$dest/usr/libexec/openclaw-paths.sh" "$dest/usr/libexec/openclaw-node.sh"
|
||||
|
||||
# LuCI controller
|
||||
mkdir -p "$dest/usr/lib/lua/luci/controller"
|
||||
cp "$PKG_DIR/luasrc/controller/openclaw.lua" "$dest/usr/lib/lua/luci/controller/"
|
||||
|
||||
# Shared Lua helpers
|
||||
mkdir -p "$dest/usr/lib/lua/openclaw"
|
||||
cp "$PKG_DIR/luasrc/openclaw/paths.lua" "$dest/usr/lib/lua/openclaw/"
|
||||
|
||||
# LuCI CBI
|
||||
mkdir -p "$dest/usr/lib/lua/luci/model/cbi/openclaw"
|
||||
cp "$PKG_DIR/luasrc/model/cbi/openclaw/"*.lua "$dest/usr/lib/lua/luci/model/cbi/openclaw/"
|
||||
|
||||
43
tests/test_node_packaging_contract.sh
Normal file
43
tests/test_node_packaging_contract.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)
|
||||
|
||||
BUILD_SCRIPT="$REPO_ROOT/scripts/build-node-musl.sh"
|
||||
WORKFLOW="$REPO_ROOT/.github/workflows/build-node-musl.yml"
|
||||
MAKEFILE="$REPO_ROOT/Makefile"
|
||||
BUILD_IPK="$REPO_ROOT/scripts/build_ipk.sh"
|
||||
BUILD_RUN="$REPO_ROOT/scripts/build_run.sh"
|
||||
ENV_SCRIPT="$REPO_ROOT/root/usr/bin/openclaw-env"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep -Fq 'patchelf --set-interpreter "/lib/ld-musl-aarch64.so.1"' "$BUILD_SCRIPT" || fail "build script should use system musl loader"
|
||||
grep -Fq '$ORIGIN/../lib' "$BUILD_SCRIPT" || fail "build script should use relative rpath"
|
||||
if grep -Fq 'patchelf --set-interpreter "${INSTALL_PREFIX}/lib/ld-musl-aarch64.so.1"' "$BUILD_SCRIPT"; then
|
||||
fail "build script should not hardcode interpreter to install prefix"
|
||||
fi
|
||||
|
||||
grep -Fq 'verify_prefix /opt/openclaw/node' "$WORKFLOW" || fail "workflow should verify default install path"
|
||||
grep -Fq 'verify_prefix /tmp/custom-openclaw-root/openclaw/node' "$WORKFLOW" || fail "workflow should verify custom install path"
|
||||
|
||||
grep -Fq 'oc_node_version_ge "$installed_ver" "$node_ver"' "$ENV_SCRIPT" || fail "installer should enforce minimum node version after extraction"
|
||||
if grep -Fq 'mirror_list="$mirror_list ${NODE_SELF_HOST}/${v1_tarball}"' "$ENV_SCRIPT"; then
|
||||
fail "installer should not auto-fallback from V2 to V1 tarball"
|
||||
fi
|
||||
|
||||
grep -Fq 'openclaw-paths.sh' "$MAKEFILE" || fail "package makefile should install path helper"
|
||||
grep -Fq 'openclaw-node.sh' "$MAKEFILE" || fail "package makefile should install node helper"
|
||||
grep -Fq 'openclaw/paths.lua' "$MAKEFILE" || fail "package makefile should install Lua path helper"
|
||||
grep -Fq 'openclaw-paths.sh' "$BUILD_IPK" || fail "ipk builder should package path helper"
|
||||
grep -Fq 'openclaw-node.sh' "$BUILD_IPK" || fail "ipk builder should package node helper"
|
||||
grep -Fq 'openclaw/paths.lua' "$BUILD_IPK" || fail "ipk builder should package Lua path helper"
|
||||
grep -Fq 'openclaw-paths.sh' "$BUILD_RUN" || fail "run builder should package path helper"
|
||||
grep -Fq 'openclaw-node.sh' "$BUILD_RUN" || fail "run builder should package node helper"
|
||||
grep -Fq 'openclaw/paths.lua' "$BUILD_RUN" || fail "run builder should package Lua path helper"
|
||||
|
||||
echo "ok"
|
||||
54
tests/test_openclaw_node.sh
Normal file
54
tests/test_openclaw_node.sh
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)
|
||||
|
||||
. "$REPO_ROOT/root/usr/libexec/openclaw-node.sh"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
normalized=$(oc_normalize_node_version "v22.16.1") || fail "normalize valid version"
|
||||
[ "$normalized" = "22.16.1" ] || fail "normalized version value"
|
||||
|
||||
if oc_normalize_node_version "broken-version" >/dev/null 2>&1; then
|
||||
fail "invalid version should not normalize"
|
||||
fi
|
||||
|
||||
oc_node_version_ge "22.16.0" "22.16.0" || fail "exact version should satisfy requirement"
|
||||
oc_node_version_ge "22.16.1" "22.16.0" || fail "newer patch should satisfy requirement"
|
||||
oc_node_version_ge "23.0.0" "22.16.0" || fail "newer major should satisfy requirement"
|
||||
if oc_node_version_ge "22.15.1" "22.16.0"; then
|
||||
fail "older minor version should not satisfy requirement"
|
||||
fi
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
trap 'rm -rf "$tmpdir"' EXIT INT TERM
|
||||
|
||||
cat > "$tmpdir/node-ok" <<'EOF'
|
||||
#!/bin/sh
|
||||
if [ "${1:-}" = "--version" ]; then
|
||||
echo "v22.16.2"
|
||||
exit 0
|
||||
fi
|
||||
exit 1
|
||||
EOF
|
||||
chmod +x "$tmpdir/node-ok"
|
||||
|
||||
cat > "$tmpdir/node-bad" <<'EOF'
|
||||
#!/bin/sh
|
||||
exit 127
|
||||
EOF
|
||||
chmod +x "$tmpdir/node-bad"
|
||||
|
||||
read_ver=$(oc_read_node_version "$tmpdir/node-ok") || fail "read runnable node version"
|
||||
[ "$read_ver" = "22.16.2" ] || fail "read version value"
|
||||
|
||||
if oc_read_node_version "$tmpdir/node-bad" >/dev/null 2>&1; then
|
||||
fail "broken node binary should not be accepted"
|
||||
fi
|
||||
|
||||
echo "ok"
|
||||
Reference in New Issue
Block a user