mirror of
https://github.com/hotwa/luci-app-openclaw.git
synced 2026-03-30 20:25:44 +00:00
Fix ARM64 musl node download discovery
This commit is contained in:
@@ -4,6 +4,9 @@ module("luci.controller.openclaw", package.seeall)
|
|||||||
local nixio_fs = require "nixio.fs"
|
local nixio_fs = require "nixio.fs"
|
||||||
local util = require "luci.util"
|
local util = require "luci.util"
|
||||||
local oc_paths = require "openclaw.paths"
|
local oc_paths = require "openclaw.paths"
|
||||||
|
local GITHUB_REPO = "hotwa/luci-app-openclaw"
|
||||||
|
local GITHUB_RELEASES_URL = "https://github.com/" .. GITHUB_REPO .. "/releases"
|
||||||
|
local GITHUB_API_RELEASES_URL = "https://api.github.com/repos/" .. GITHUB_REPO .. "/releases"
|
||||||
|
|
||||||
local function get_install_root_from_uci()
|
local function get_install_root_from_uci()
|
||||||
return require("luci.model.uci").cursor():get("openclaw", "main", "install_root")
|
return require("luci.model.uci").cursor():get("openclaw", "main", "install_root")
|
||||||
@@ -448,7 +451,7 @@ function action_check_update()
|
|||||||
local plugin_has_update = false
|
local plugin_has_update = false
|
||||||
|
|
||||||
-- 使用 GitHub API 获取最新 release (tag + body)
|
-- 使用 GitHub API 获取最新 release (tag + body)
|
||||||
local gh_json = sys.exec("curl -sf --connect-timeout 5 --max-time 10 'https://api.github.com/repos/10000ge10000/luci-app-openclaw/releases/latest' 2>/dev/null")
|
local gh_json = sys.exec("curl -sf --connect-timeout 5 --max-time 10 '" .. GITHUB_API_RELEASES_URL .. "/latest' 2>/dev/null")
|
||||||
if gh_json and gh_json ~= "" then
|
if gh_json and gh_json ~= "" then
|
||||||
-- 提取 tag_name
|
-- 提取 tag_name
|
||||||
local tag = gh_json:match('"tag_name"%s*:%s*"([^"]+)"')
|
local tag = gh_json:match('"tag_name"%s*:%s*"([^"]+)"')
|
||||||
@@ -551,7 +554,7 @@ function action_plugin_upgrade()
|
|||||||
sys.exec("rm -f /tmp/openclaw-plugin-upgrade.log /tmp/openclaw-plugin-upgrade.pid /tmp/openclaw-plugin-upgrade.exit")
|
sys.exec("rm -f /tmp/openclaw-plugin-upgrade.log /tmp/openclaw-plugin-upgrade.pid /tmp/openclaw-plugin-upgrade.exit")
|
||||||
|
|
||||||
-- 后台执行: 下载 .run 并执行安装
|
-- 后台执行: 下载 .run 并执行安装
|
||||||
local run_url = "https://github.com/10000ge10000/luci-app-openclaw/releases/download/v" .. version .. "/luci-app-openclaw_" .. version .. ".run"
|
local run_url = GITHUB_RELEASES_URL .. "/download/v" .. version .. "/luci-app-openclaw_" .. version .. ".run"
|
||||||
-- 使用 curl 下载 (-L 跟随重定向), 然后 sh 执行
|
-- 使用 curl 下载 (-L 跟随重定向), 然后 sh 执行
|
||||||
sys.exec(string.format(
|
sys.exec(string.format(
|
||||||
"( echo '正在下载插件 v%s ...' > /tmp/openclaw-plugin-upgrade.log; " ..
|
"( echo '正在下载插件 v%s ...' > /tmp/openclaw-plugin-upgrade.log; " ..
|
||||||
|
|||||||
@@ -251,9 +251,13 @@ act.cfgvalue = function(self, section)
|
|||||||
html[#html+1] = 'if(log.indexOf("当前已安装在")>=0||log.indexOf("检测目录不存在")>=0||log.indexOf("安装根目录")>=0){'
|
html[#html+1] = 'if(log.indexOf("当前已安装在")>=0||log.indexOf("检测目录不存在")>=0||log.indexOf("安装根目录")>=0){'
|
||||||
html[#html+1] = 'reasons.push("📁 <b>安装目录配置有误</b> — 请选择已挂载的绝对路径;如果当前环境已经安装在其他目录,请先卸载后再切换。");'
|
html[#html+1] = 'reasons.push("📁 <b>安装目录配置有误</b> — 请选择已挂载的绝对路径;如果当前环境已经安装在其他目录,请先卸载后再切换。");'
|
||||||
html[#html+1] = '}'
|
html[#html+1] = '}'
|
||||||
-- 网络问题
|
-- ARM64 musl 专属下载问题
|
||||||
html[#html+1] = 'if(ll.indexOf("could not resolve")>=0||ll.indexOf("connection timed out")>=0||ll.indexOf("curl")>=0&&ll.indexOf("fail")>=0||ll.indexOf("wget")>=0&&ll.indexOf("fail")>=0||ll.indexOf("所有镜像均下载失败")>=0){'
|
html[#html+1] = 'if(ll.indexOf("arm64 musl")>=0&&(ll.indexOf("release api")>=0||ll.indexOf("node-bins")>=0||ll.indexOf("未找到兼容的 arm64 musl node.js 资产")>=0||ll.indexOf("无法获取 arm64 musl node.js 发布元数据")>=0)){'
|
||||||
html[#html+1] = 'reasons.push("🌐 <b>网络连接失败</b> — 无法下载 Node.js。请检查路由器是否能访问外网。<br/> 💡 解决: 检查 DNS 设置和网络连接,或手动指定镜像: <code>NODE_MIRROR=https://npmmirror.com/mirrors/node openclaw-env setup</code>");'
|
html[#html+1] = 'reasons.push("🧩 <b>ARM64 musl Node.js 资产不可用</b> — 当前设备依赖仓库发布的 <code>node-bins</code> 资产,而不是通用 Node 镜像。<br/> 💡 解决: 检查 <code>hotwa/luci-app-openclaw</code> 的 <code>node-bins</code> release 是否存在满足 <code>>=22.16.0</code> 的 <code>linux-arm64-musl</code> 资产,并确认路由器可访问 GitHub API 与 release 页面。");'
|
||||||
|
html[#html+1] = '}'
|
||||||
|
-- 通用网络问题
|
||||||
|
html[#html+1] = 'if((ll.indexOf("could not resolve")>=0||ll.indexOf("connection timed out")>=0||ll.indexOf("curl")>=0&&ll.indexOf("fail")>=0||ll.indexOf("wget")>=0&&ll.indexOf("fail")>=0||ll.indexOf("所有镜像均下载失败")>=0)&&!(ll.indexOf("arm64 musl")>=0&&(ll.indexOf("release api")>=0||ll.indexOf("node-bins")>=0||ll.indexOf("未找到兼容的 arm64 musl node.js 资产")>=0||ll.indexOf("无法获取 arm64 musl node.js 发布元数据")>=0))){'
|
||||||
|
html[#html+1] = 'reasons.push("🌐 <b>网络连接失败</b> — 无法下载 Node.js。请检查路由器是否能访问外网。<br/> 💡 解决: 检查 DNS 设置、网络连通性以及当前默认下载源是否可访问;如有需要,可通过环境变量覆盖下载源后重试。");'
|
||||||
html[#html+1] = '}'
|
html[#html+1] = '}'
|
||||||
-- 磁盘空间
|
-- 磁盘空间
|
||||||
html[#html+1] = 'if(ll.indexOf("no space")>=0||ll.indexOf("disk full")>=0||ll.indexOf("enospc")>=0){'
|
html[#html+1] = 'if(ll.indexOf("no space")>=0||ll.indexOf("disk full")>=0||ll.indexOf("enospc")>=0){'
|
||||||
@@ -331,7 +335,7 @@ act.cfgvalue = function(self, section)
|
|||||||
html[#html+1] = '}'
|
html[#html+1] = '}'
|
||||||
html[#html+1] = 'act.innerHTML=notesHtml'
|
html[#html+1] = 'act.innerHTML=notesHtml'
|
||||||
html[#html+1] = '+\'<button class="btn cbi-button cbi-button-apply" type="button" onclick="ocPluginUpgrade()" id="btn-plugin-upgrade">⬆️ 升级插件 v\'+r.plugin_latest+\'</button>\''
|
html[#html+1] = '+\'<button class="btn cbi-button cbi-button-apply" type="button" onclick="ocPluginUpgrade()" id="btn-plugin-upgrade">⬆️ 升级插件 v\'+r.plugin_latest+\'</button>\''
|
||||||
html[#html+1] = '+\' <a href="https://github.com/10000ge10000/luci-app-openclaw/releases/latest" target="_blank" rel="noopener" class="btn cbi-button cbi-button-action" style="text-decoration:none;">📥 手动下载</a>\';'
|
html[#html+1] = '+\' <a href="https://github.com/hotwa/luci-app-openclaw/releases/latest" target="_blank" rel="noopener" class="btn cbi-button cbi-button-action" style="text-decoration:none;">📥 手动下载</a>\';'
|
||||||
html[#html+1] = '}'
|
html[#html+1] = '}'
|
||||||
html[#html+1] = '}catch(e){el.innerHTML="<span style=\\"color:red\\">❌ 检测失败</span>";}'
|
html[#html+1] = '}catch(e){el.innerHTML="<span style=\\"color:red\\">❌ 检测失败</span>";}'
|
||||||
html[#html+1] = '});}'
|
html[#html+1] = '});}'
|
||||||
@@ -614,8 +618,8 @@ guide.cfgvalue = function()
|
|||||||
html[#html+1] = '<a href="https://space.bilibili.com/59438380" target="_blank" rel="noopener" style="color:#00a1d6;font-weight:bold;text-decoration:none;">'
|
html[#html+1] = '<a href="https://space.bilibili.com/59438380" target="_blank" rel="noopener" style="color:#00a1d6;font-weight:bold;text-decoration:none;">'
|
||||||
html[#html+1] = '🔗 space.bilibili.com/59438380</a>'
|
html[#html+1] = '🔗 space.bilibili.com/59438380</a>'
|
||||||
html[#html+1] = '<span style="margin-left:16px;color:#888;">GitHub 项目:</span>'
|
html[#html+1] = '<span style="margin-left:16px;color:#888;">GitHub 项目:</span>'
|
||||||
html[#html+1] = '<a href="https://github.com/10000ge10000/luci-app-openclaw" target="_blank" rel="noopener" style="color:#24292f;font-weight:bold;text-decoration:none;">'
|
html[#html+1] = '<a href="https://github.com/hotwa/luci-app-openclaw" target="_blank" rel="noopener" style="color:#24292f;font-weight:bold;text-decoration:none;">'
|
||||||
html[#html+1] = '🐙 10000ge10000/luci-app-openclaw</a></div></div>'
|
html[#html+1] = '🐙 hotwa/luci-app-openclaw</a></div></div>'
|
||||||
return table.concat(html, "\n")
|
return table.concat(html, "\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -53,13 +53,14 @@ NODE_BIN="${NODE_BASE}/bin/node"
|
|||||||
NPM_BIN="${NODE_BASE}/bin/npm"
|
NPM_BIN="${NODE_BASE}/bin/npm"
|
||||||
PNPM_BIN="${OC_GLOBAL}/bin/pnpm"
|
PNPM_BIN="${OC_GLOBAL}/bin/pnpm"
|
||||||
|
|
||||||
# Node.js 官方镜像 + musl 非官方构建
|
# Node.js 下载源
|
||||||
# Node.js 官方镜像 + musl 非官方构建
|
OPENCLAW_GITHUB_REPO="${OPENCLAW_GITHUB_REPO:-hotwa/luci-app-openclaw}"
|
||||||
NODE_MIRROR="${NODE_MIRROR:-https://nodejs.org/dist}"
|
NODE_MIRROR="${NODE_MIRROR:-https://nodejs.org/dist}"
|
||||||
NODE_MIRROR_CN="https://npmmirror.com/mirrors/node"
|
NODE_MIRROR_CN="https://npmmirror.com/mirrors/node"
|
||||||
NODE_MUSL_MIRROR="https://unofficial-builds.nodejs.org/download/release"
|
NODE_MUSL_MIRROR="https://unofficial-builds.nodejs.org/download/release"
|
||||||
# 项目自托管 ARM64 musl Node.js (unofficial-builds 仅提供 x64 musl)
|
NODE_SELF_HOST="${NODE_SELF_HOST:-https://github.com/${OPENCLAW_GITHUB_REPO}/releases/download/node-bins}"
|
||||||
NODE_SELF_HOST="https://github.com/10000ge10000/luci-app-openclaw/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 PATH="${NODE_BASE}/bin:${OC_GLOBAL}/bin:$PATH"
|
||||||
export NODE_ICU_DATA="${NODE_BASE}/share/icu"
|
export NODE_ICU_DATA="${NODE_BASE}/share/icu"
|
||||||
@@ -68,6 +69,48 @@ log_info() { echo " [✓] $1"; }
|
|||||||
log_warn() { echo " [!] $1"; }
|
log_warn() { echo " [!] $1"; }
|
||||||
log_error() { 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 后使用标准路径)
|
# 安全创建目录 (会在 _oc_fix_opt 修复 /opt 后使用标准路径)
|
||||||
ensure_mkdir() {
|
ensure_mkdir() {
|
||||||
local target="$1"
|
local target="$1"
|
||||||
@@ -169,17 +212,16 @@ download_node() {
|
|||||||
local mirror_list=""
|
local mirror_list=""
|
||||||
local musl_tarball="node-v${node_ver}-${node_arch}-musl.tar.xz"
|
local musl_tarball="node-v${node_ver}-${node_arch}-musl.tar.xz"
|
||||||
local glibc_tarball="node-v${node_ver}-${node_arch}.tar.xz"
|
local glibc_tarball="node-v${node_ver}-${node_arch}.tar.xz"
|
||||||
|
local arm64_musl_url=""
|
||||||
|
|
||||||
if [ "$libc_type" = "musl" ]; then
|
if [ "$libc_type" = "musl" ]; then
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== 下载 Node.js v${node_ver} (${node_arch}, musl libc) ==="
|
echo "=== 下载 Node.js v${node_ver} (${node_arch}, musl libc) ==="
|
||||||
|
|
||||||
if [ "$node_arch" = "linux-arm64" ]; then
|
if [ "$node_arch" = "linux-arm64" ]; then
|
||||||
# ARM64 musl: unofficial-builds 不提供,从项目自托管下载
|
# ARM64 musl: 从当前维护仓库的 node-bins release 动态选择兼容资产
|
||||||
# 1) 项目自托管 ARM64 musl 构建 (当前版本)
|
arm64_musl_url=$(resolve_arm64_musl_node_url "$node_ver") || exit 1
|
||||||
mirror_list="${NODE_SELF_HOST}/${musl_tarball}"
|
mirror_list="${arm64_musl_url}"
|
||||||
# 2) unofficial-builds (留作将来可能支持)
|
|
||||||
mirror_list="$mirror_list ${NODE_MUSL_MIRROR}/v${node_ver}/${musl_tarball}"
|
|
||||||
else
|
else
|
||||||
# x64 musl: unofficial-builds 提供
|
# x64 musl: unofficial-builds 提供
|
||||||
# 1) unofficial-builds
|
# 1) unofficial-builds
|
||||||
|
|||||||
@@ -66,3 +66,53 @@ oc_read_node_version() {
|
|||||||
version=$("$node_bin" --version 2>/dev/null) || return 1
|
version=$("$node_bin" --version 2>/dev/null) || return 1
|
||||||
oc_normalize_node_version "$version"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
# 使用 patchelf 修改 node 二进制的 ELF interpreter 和 rpath,
|
# 使用 patchelf 修改 node 二进制的 ELF interpreter 和 rpath,
|
||||||
# 使其使用系统 musl 动态链接器和相对 rpath,可从任意安装根目录直接运行。
|
# 使其使用系统 musl 动态链接器和相对 rpath,可从任意安装根目录直接运行。
|
||||||
# 这样 process.execPath 返回正确的 node 路径,子进程 fork 也能正常工作。
|
# 这样 process.execPath 返回正确的 node 路径,子进程 fork 也能正常工作。
|
||||||
|
# 注意: 运行时把 NODE_VERSION 视为最低要求,不要求发布资产文件名与最低要求版本完全相同。
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ MAKEFILE="$REPO_ROOT/Makefile"
|
|||||||
BUILD_IPK="$REPO_ROOT/scripts/build_ipk.sh"
|
BUILD_IPK="$REPO_ROOT/scripts/build_ipk.sh"
|
||||||
BUILD_RUN="$REPO_ROOT/scripts/build_run.sh"
|
BUILD_RUN="$REPO_ROOT/scripts/build_run.sh"
|
||||||
ENV_SCRIPT="$REPO_ROOT/root/usr/bin/openclaw-env"
|
ENV_SCRIPT="$REPO_ROOT/root/usr/bin/openclaw-env"
|
||||||
|
CONTROLLER_SCRIPT="$REPO_ROOT/luasrc/controller/openclaw.lua"
|
||||||
|
BASIC_LUA="$REPO_ROOT/luasrc/model/cbi/openclaw/basic.lua"
|
||||||
|
|
||||||
fail() {
|
fail() {
|
||||||
echo "FAIL: $1" >&2
|
echo "FAIL: $1" >&2
|
||||||
@@ -29,6 +31,14 @@ grep -Fq 'oc_node_version_ge "$installed_ver" "$node_ver"' "$ENV_SCRIPT" || fail
|
|||||||
if grep -Fq 'mirror_list="$mirror_list ${NODE_SELF_HOST}/${v1_tarball}"' "$ENV_SCRIPT"; then
|
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"
|
fail "installer should not auto-fallback from V2 to V1 tarball"
|
||||||
fi
|
fi
|
||||||
|
grep -Fq 'OPENCLAW_GITHUB_REPO="${OPENCLAW_GITHUB_REPO:-hotwa/luci-app-openclaw}"' "$ENV_SCRIPT" || fail "installer should default to hotwa repo"
|
||||||
|
grep -Fq 'NODE_SELF_HOST="${NODE_SELF_HOST:-https://github.com/${OPENCLAW_GITHUB_REPO}/releases/download/node-bins}"' "$ENV_SCRIPT" || fail "installer should derive node-bins release URL from hotwa repo"
|
||||||
|
grep -Fq 'NODE_RELEASE_API="${NODE_RELEASE_API:-https://api.github.com/repos/${OPENCLAW_GITHUB_REPO}/releases/tags/node-bins}"' "$ENV_SCRIPT" || fail "installer should derive node-bins release API from hotwa repo"
|
||||||
|
grep -Fq 'oc_select_node_release_asset_url' "$ENV_SCRIPT" || fail "installer should dynamically select ARM64 musl asset"
|
||||||
|
grep -Fq 'arm64_musl_url=$(resolve_arm64_musl_node_url "$node_ver") || exit 1' "$ENV_SCRIPT" || fail "installer should resolve ARM64 musl asset dynamically"
|
||||||
|
if grep -Fq 'mirror_list="${NODE_SELF_HOST}/${musl_tarball}"' "$ENV_SCRIPT"; then
|
||||||
|
fail "installer should not hardcode exact ARM64 musl asset path"
|
||||||
|
fi
|
||||||
|
|
||||||
grep -Fq 'openclaw-paths.sh' "$MAKEFILE" || fail "package makefile should install path helper"
|
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-node.sh' "$MAKEFILE" || fail "package makefile should install node helper"
|
||||||
@@ -43,5 +53,13 @@ grep -Fq 'openclaw/paths.lua' "$BUILD_IPK" || fail "ipk builder should package L
|
|||||||
grep -Fq 'openclaw-paths.sh' "$BUILD_RUN" || fail "run builder should package 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-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"
|
grep -Fq 'openclaw/paths.lua' "$BUILD_RUN" || fail "run builder should package Lua path helper"
|
||||||
|
grep -Fq 'local GITHUB_REPO = "hotwa/luci-app-openclaw"' "$CONTROLLER_SCRIPT" || fail "controller should default to hotwa repo"
|
||||||
|
grep -Fq 'local GITHUB_RELEASES_URL = "https://github.com/" .. GITHUB_REPO .. "/releases"' "$CONTROLLER_SCRIPT" || fail "controller should derive release URLs from hotwa repo"
|
||||||
|
grep -Fq 'local GITHUB_API_RELEASES_URL = "https://api.github.com/repos/" .. GITHUB_REPO .. "/releases"' "$CONTROLLER_SCRIPT" || fail "controller should derive API URLs from hotwa repo"
|
||||||
|
grep -Fq "https://github.com/hotwa/luci-app-openclaw/releases/latest" "$BASIC_LUA" || fail "UI should link manual download to hotwa repo"
|
||||||
|
grep -Fq "ARM64 musl" "$BASIC_LUA" || fail "UI should mention ARM64 musl specific guidance"
|
||||||
|
if grep -Fq 'NODE_MIRROR=https://npmmirror.com/mirrors/node openclaw-env setup' "$BASIC_LUA"; then
|
||||||
|
fail "UI should not recommend NODE_MIRROR for ARM64 musl node download failures"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "ok"
|
echo "ok"
|
||||||
|
|||||||
@@ -51,4 +51,31 @@ if oc_read_node_version "$tmpdir/node-bad" >/dev/null 2>&1; then
|
|||||||
fail "broken node binary should not be accepted"
|
fail "broken node binary should not be accepted"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
cat > "$tmpdir/node-bins-release.json" <<'EOF'
|
||||||
|
{
|
||||||
|
"tag_name": "node-bins",
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"name": "node-v22.15.1-linux-arm64-musl.tar.xz",
|
||||||
|
"browser_download_url": "https://github.com/hotwa/luci-app-openclaw/releases/download/node-bins/node-v22.15.1-linux-arm64-musl.tar.xz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node-v23.2.0-linux-arm64-musl.tar.xz",
|
||||||
|
"browser_download_url": "https://github.com/hotwa/luci-app-openclaw/releases/download/node-bins/node-v23.2.0-linux-arm64-musl.tar.xz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node-v22.16.0-linux-x64-musl.tar.xz",
|
||||||
|
"browser_download_url": "https://github.com/hotwa/luci-app-openclaw/releases/download/node-bins/node-v22.16.0-linux-x64-musl.tar.xz"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
selected_url=$(oc_select_node_release_asset_url "$tmpdir/node-bins-release.json" "linux-arm64" "22.16.0") || fail "select compatible ARM64 musl asset"
|
||||||
|
[ "$selected_url" = "https://github.com/hotwa/luci-app-openclaw/releases/download/node-bins/node-v23.2.0-linux-arm64-musl.tar.xz" ] || fail "selected asset should be newest compatible ARM64 musl release"
|
||||||
|
|
||||||
|
if oc_select_node_release_asset_url "$tmpdir/node-bins-release.json" "linux-arm64" "24.0.0" >/dev/null 2>&1; then
|
||||||
|
fail "asset selection should fail when no compatible version exists"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "ok"
|
echo "ok"
|
||||||
|
|||||||
Reference in New Issue
Block a user