Download entrypoint.sh from Supertbot/suing: direct link, hf CLI and curl.
- Browser
- Download file 5.15 kB
-
https://huggingface.co/spaces/Supertbot/suing/resolve/main/entrypoint.sh
- Command line
-
hf download hf://spaces/Supertbot/suing/entrypoint.sh
-
curl -L -o entrypoint.sh https://huggingface.co/spaces/Supertbot/suing/resolve/main/entrypoint.sh
5.15 kB
| # 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 | |