File size: 5,147 Bytes
0a24085 6f71136 f766c15 ab84502 6f71136 f766c15 6f71136 f766c15 6f71136 f766c15 6f71136 f766c15 6f71136 f766c15 6f71136 f766c15 6f71136 f766c15 6f71136 f766c15 6f71136 f766c15 f3fd450 6f71136 f3fd450 6f71136 f3fd450 6f71136 f3fd450 6f71136 f3fd450 f766c15 6f71136 f766c15 f3fd450 6f71136 f3fd450 f766c15 f3fd450 6f71136 f3fd450 f766c15 f3fd450 6f71136 f766c15 f3fd450 f766c15 6f71136 c4f6f73 f766c15 6f71136 f766c15 6f71136 f766c15 6f71136 f766c15 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #!/bin/sh
# OpenClaw on HF Spaces - 实时状态在本地磁盘, /data 仅只读导入旧配置/工作区
umask 022
ts() { date -u +"%H:%M:%S"; }
log() { echo "[$(ts)] [entrypoint] $*"; }
warn() { echo "[$(ts)] [entrypoint] WARN: $*"; }
OPENCLAW_HOME=/home/user
mkdir -p "$OPENCLAW_HOME/.openclaw"
export OPENCLAW_HOME
log "OPENCLAW_HOME=$OPENCLAW_HOME (live state on local disk)"
# ── 从 Secrets 导出各家 Key ──
for VAR in $(env | cut -d= -f1); do
case "$VAR" in OPENCLAW_*|SPACE_*|SYSTEM_*|HF_*|NODE_*|npm_*) continue ;; esac
case "$VAR" in
*_API_KEY|*_SECRET_KEY|*_ACCESS_TOKEN|*_BOT_TOKEN|*_AUTH_TOKEN|*_APP_KEY)
[ -n "$(printenv "$VAR" 2>/dev/null)" ] && { export "$VAR"; log "exported: $VAR"; } ;;
esac
done
# ── 生成配置 + 安全检查 ──
log "Running setup..."
node /app/spaces/huggingface/setup-hf-config.mjs || warn "setup failed"
sh /app/security-check.sh || true
# ── doctor (本地新状态, 做一次迁移/校验) ──
log "Running openclaw doctor --fix..."
timeout 300 openclaw doctor --fix --non-interactive </dev/null >/tmp/doctor.out 2>&1
tail -n 30 /tmp/doctor.out
chmod -R go-w "$OPENCLAW_HOME/.openclaw/npm" "$OPENCLAW_HOME/.openclaw/extensions" 2>/dev/null || true
GW_URL="ws://127.0.0.1:7860"
GW_TOKEN="${OPENCLAW_GATEWAY_TOKEN:-}"
if [ -z "$GW_TOKEN" ]; then
GW_TOKEN=$(node -e 'try{console.log(JSON.parse(require("fs").readFileSync(process.env.OPENCLAW_HOME+"/.openclaw/openclaw.json","utf8")).gateway.auth.token||"")}catch(e){}' 2>/dev/null)
fi
for kv in "gateway.mode local" "gateway.port 7860"; do
set -- $kv
openclaw config set "$1" "$2" </dev/null >/tmp/cfg.out 2>&1 \
&& log "config set $1 = $2" || warn "config set $1 failed: $(head -c 200 /tmp/cfg.out | tr '\n' ' ')"
done
# ── Telegram 网络: 启动先探测一次, 之后后台持续重试 ──
export TG_IP_CACHE=/tmp/tg-ips.json
GW_NODE_OPTIONS="--dns-result-order=ipv4first"
if [ "${TG_NET_FIX:-1}" = "1" ]; then
log "Probing api.telegram.org..."
timeout 30 node /app/tg-net-fix.cjs probe || true
GW_NODE_OPTIONS="$GW_NODE_OPTIONS --require /app/tg-net-fix.cjs"
( while true; do sleep 45; timeout 40 node /app/tg-net-fix.cjs probe quiet; done ) &
fi
# ── 只靠密码登录: 通过网关认证后才会出现配对请求, 自动批准 ──
UUID_RE='[0-9a-f]\{8\}-[0-9a-f]\{4\}-[0-9a-f]\{4\}-[0-9a-f]\{4\}-[0-9a-f]\{12\}'
try_approve() {
ID="$1"
grep -qx "$ID" /tmp/approved.ids 2>/dev/null && return 0
N=$(cat "/tmp/fail.$ID" 2>/dev/null || echo 0)
[ "$N" -ge 2 ] && return 0
if openclaw devices approve "$ID" --url "$GW_URL" --token "$GW_TOKEN" </dev/null >/tmp/approve.out 2>&1 \
|| openclaw devices approve "$ID" </dev/null >/tmp/approve.out 2>&1; then
echo "$ID" >> /tmp/approved.ids
log "Approved pairing request $ID"
else
echo $((N+1)) > "/tmp/fail.$ID"
warn "approve failed for $ID: $(head -c 300 /tmp/approve.out | tr '\n' ' ')"
fi
}
if [ "${AUTO_APPROVE_PAIRING:-1}" = "1" ]; then
(
log "Pairing auto-approver started"
while true; do
sleep 4
IDS=""
if openclaw devices list --json --url "$GW_URL" --token "$GW_TOKEN" </dev/null >/tmp/devices.json 2>/dev/null \
|| openclaw devices list --json </dev/null >/tmp/devices.json 2>/dev/null; then
IDS=$(node - <<'JSEOF'
const fs = require('fs');
let data;
try { data = JSON.parse(fs.readFileSync('/tmp/devices.json', 'utf8')); } catch (e) { process.exit(0); }
const out = [];
(function walk(v, key) {
if (Array.isArray(v)) {
const pending = /pending/i.test(key || '');
for (const x of v) {
if (pending && x && typeof x === 'object') {
const id = x.requestId || x.id;
if (typeof id === 'string') out.push(id);
} else walk(x, key);
}
} else if (v && typeof v === 'object') {
for (const k of Object.keys(v)) walk(v[k], k);
}
})(data, '');
console.log(out.join('\n'));
JSEOF
)
fi
LOGIDS=""
LATEST=$(ls -t /tmp/openclaw/openclaw-*.log 2>/dev/null | head -n 1)
[ -n "$LATEST" ] && LOGIDS=$(tail -n 300 "$LATEST" 2>/dev/null \
| grep -o "requestId[^0-9a-f]\{0,4\}$UUID_RE" | grep -o "$UUID_RE" | sort -u)
for ID in $IDS $LOGIDS; do try_approve "$ID"; done
done
) &
fi
# ── 网关循环 ──
for U in "${TELEGRAM_API_ROOT}/bot0:x/getMe" "https://api.telegram.org/bot0:x/getMe" "https://example.com"; do
log "net-test $U -> $(curl -sS -m 10 -o /dev/null -w 'http=%{http_code} connect=%{time_connect}s tls=%{time_appconnect}s' "$U" 2>&1 | tr '\n' ' ')"
done
log "Starting gateway loop..."
while true; do
for d in "$OPENCLAW_HOME"/.openclaw/tmp/openclaw-*; do
[ -d "$d" ] && rm -f "$d"/*.lock 2>/dev/null
done
log "Gateway starting..."
NODE_OPTIONS="$GW_NODE_OPTIONS ${NODE_OPTIONS:-}" openclaw gateway --allow-unconfigured --bind lan --port 7860
CODE=$?
log "Gateway exited (code $CODE)"
WAITED=0
while nc -z 127.0.0.1 7860 2>/dev/null; do
[ $WAITED -eq 0 ] && log "Port 7860 still held - waiting..."
sleep 2; WAITED=$((WAITED + 2))
[ $WAITED -ge 90 ] && { warn "Port still in use after 90s - forcing restart"; break; }
done
sleep 1
done
|