🍉 Sync 2026-05-16 08:37:13

This commit is contained in:
github-actions[bot] committed 2026-05-16 08:37:13 +08:00
1 parent 8c1c3dd8ec
commit 8ed4c2a2a5
32 files changed
+1145 -234

No files matched your search

+57
View File
@@ -0,0 +1,57 @@
#!/bin/sh
# OpenClaw Node.js 版本校验工具。
oc_normalize_node_version() {
local raw="${1:-}"
raw=${raw#v}
case "$raw" in
[0-9]*.[0-9]*.[0-9]*) printf '%s\n' "$raw"; return 0 ;;
esac
return 1
}
oc_read_node_version() {
local node_bin="$1"
local raw
[ -x "$node_bin" ] || return 1
raw=$("$node_bin" --version 2>/dev/null) || return 1
oc_normalize_node_version "$raw"
}
oc_node_version_ge() {
local current required
current=$(oc_normalize_node_version "$1") || return 1
required=$(oc_normalize_node_version "$2") || return 1
awk -v a="$current" -v b="$required" '
BEGIN {
split(a, av, "."); split(b, bv, ".");
for (i = 1; i <= 3; i++) {
ai = av[i] + 0; bi = bv[i] + 0;
if (ai > bi) exit 0;
if (ai < bi) exit 1;
}
exit 0;
}
'
}
oc_assert_node_min_version() {
local node_bin="$1"
local required="$2"
local current
current=$(oc_read_node_version "$node_bin") || {
echo " [✗] Node.js 不可执行或无法读取版本: $node_bin"
return 1
}
if ! oc_node_version_ge "$current" "$required"; then
echo " [✗] Node.js v${current} 低于 OpenClaw 要求 v${required}"
echo " [!] 请重新运行 openclaw-env node 或 openclaw-env setup 更新运行时"
return 1
fi
echo " [✓] Node.js v${current} 满足要求 (>= v${required})"
return 0
}
+111
View File
@@ -0,0 +1,111 @@
#!/bin/sh
# luci-app-openclaw 统一路径解析工具
#
# 为什么单独抽出来:
# OpenClaw 的安装根目录会被 init、openclaw-env、Web PTY、LuCI 控制器等多处使用。
# 如果每处都自己拼路径,用户输入 /mnt/data/openclaw 时就容易得到
# /mnt/data/openclaw/openclaw 这种错误路径,后续权限修复和卸载也会变得危险。
oc_normalize_install_path() {
local raw="${1:-}"
# 空值统一回到 /opt,保持历史兼容。
[ -n "$raw" ] || raw="/opt"
# 去掉首尾空白和末尾斜杠。OpenWrt busybox sed 支持基础表达式。
raw=$(printf '%s' "$raw" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s:/*$::')
[ -n "$raw" ] || raw="/"
case "$raw" in
/*) ;;
*) return 1 ;;
esac
case "$raw" in
*[\ \ ]*|*\'*|*\"*|*\`*|*\$*|*\;*|*\&*|*\|*|*\<*|*\>*|*\(*|*\)*)
return 1
;;
esac
case "$raw" in
/|/proc|/proc/*|/sys|/sys/*|/dev|/dev/*|/tmp|/tmp/*|/var|/var/*|/etc|/etc/*|/usr|/usr/*|/bin|/bin/*|/sbin|/sbin/*|/lib|/lib/*|/rom|/rom/*|/overlay|/overlay/*)
return 1
;;
esac
# 用户如果填写的是实际运行目录 /xxx/openclaw,这里回退到根目录 /xxx。
case "$raw" in
*/openclaw)
raw=${raw%/openclaw}
[ -n "$raw" ] || raw="/"
;;
esac
printf '%s\n' "$raw"
}
oc_quote() {
# POSIX 单引号转义,用于拼接少量必须经 shell 执行的命令。
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
}
oc_load_paths() {
local input="${1:-}"
local normalized
normalized=$(oc_normalize_install_path "$input") || return 1
OPENCLAW_INSTALL_PATH="$normalized"
if [ "$OPENCLAW_INSTALL_PATH" = "/" ]; then
OC_ROOT="/openclaw"
else
OC_ROOT="${OPENCLAW_INSTALL_PATH}/openclaw"
fi
NODE_BASE="${OC_ROOT}/node"
OC_GLOBAL="${OC_ROOT}/global"
OC_DATA="${OC_ROOT}/data"
CONFIG_FILE="${OC_DATA}/.openclaw/openclaw.json"
export OPENCLAW_INSTALL_PATH OC_ROOT NODE_BASE OC_GLOBAL OC_DATA CONFIG_FILE
}
oc_find_existing_path() {
local path="$1"
while [ -n "$path" ] && [ "$path" != "/" ]; do
[ -e "$path" ] && { printf '%s\n' "$path"; return 0; }
path=${path%/*}
done
printf '/\n'
}
oc_probe_writable_root() {
local base="$1"
local probe_parent
local probe_dir
probe_parent=$(oc_find_existing_path "$base")
[ -d "$probe_parent" ] || return 1
[ -w "$probe_parent" ] || return 1
probe_dir="${probe_parent}/.openclaw-write-test-$$"
if mkdir "$probe_dir" 2>/dev/null; then
rmdir "$probe_dir" 2>/dev/null || true
return 0
fi
return 1
}
oc_safe_openclaw_root() {
local root="${1:-}"
case "$root" in
*/openclaw) ;;
*) return 1 ;;
esac
case "$root" in
/openclaw|/opt/openclaw|/mnt/*/openclaw|/media/*/openclaw|/srv/*/openclaw|/overlay/upper/opt/openclaw)
return 0
;;
esac
return 1
}