Subsequently commited on
Commit
e96d53b
·
verified ·
1 Parent(s): 7bb9cb6

Update entrypoint.sh

Browse files
Files changed (1) hide show
  1. entrypoint.sh +38 -23
entrypoint.sh CHANGED
@@ -7,19 +7,17 @@ ts() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
7
  log() { echo "[$(ts)] [entrypoint] $*"; }
8
  die() { log "FATAL: $*"; exit 1; }
9
 
10
- # Telegram long-polling uses the outbound Bot API connection.
11
- # Prefer IPv4 on HF runtimes where IPv6 egress is unavailable.
12
  export NODE_OPTIONS="--dns-result-order=ipv4first ${NODE_OPTIONS:-}"
13
 
14
- # Hugging Face Storage Bucket must be mounted at /data.
15
- # Do not silently fall back to ephemeral local storage.
16
  [ -d /data ] || die "/data does not exist. Attach a persistent Storage Bucket to this Space."
17
  touch /data/.openclaw-write-test 2>/dev/null || die "/data is not writable."
18
  rm -f /data/.openclaw-write-test
19
 
20
  mkdir -p /data/.openclaw /home/user/.openclaw
21
 
22
- # One-time migration: copy old local state only when the bucket state is empty.
23
  if [ -z "$(find /data/.openclaw -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null)" ] \
24
  && [ -n "$(find /home/user/.openclaw -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null)" ]; then
25
  log "Bucket state is empty; migrating existing /home/user/.openclaw data."
@@ -32,7 +30,7 @@ export OPENCLAW_GATEWAY_PORT=7860
32
  log "OPENCLAW_HOME=$OPENCLAW_HOME"
33
  log "Gateway public port=$OPENCLAW_GATEWAY_PORT"
34
 
35
- # Run configuration writer. Any missing Secret or invalid config is fatal.
36
  log "Writing OpenClaw configuration..."
37
  node /app/spaces/huggingface/setup-hf-config.mjs \
38
  || die "setup-hf-config.mjs failed; Gateway will not be started."
@@ -40,18 +38,13 @@ node /app/spaces/huggingface/setup-hf-config.mjs \
40
  CONFIG=/data/.openclaw/openclaw.json
41
  [ -s "$CONFIG" ] || die "Configuration file was not created: $CONFIG"
42
 
43
- # Let OpenClaw perform its supported state/config migrations.
44
- # Do not edit SQLite or device pairing JSON files directly.
45
- log "Running OpenClaw doctor migration..."
46
- if command -v timeout >/dev/null 2>&1; then
47
- timeout 300 openclaw doctor --fix --non-interactive \
48
- || die "openclaw doctor failed; inspect the doctor output above."
49
- else
50
- openclaw doctor --fix --non-interactive \
51
- || die "openclaw doctor failed; inspect the doctor output above."
52
- fi
53
 
54
- # Plugin directories must not be group/world writable.
55
  chmod -R go-w /data/.openclaw/npm /data/.openclaw/extensions 2>/dev/null || true
56
 
57
  if [ -f /app/security-check.sh ]; then
@@ -59,16 +52,38 @@ if [ -f /app/security-check.sh ]; then
59
  sh /app/security-check.sh || log "WARNING: security-check.sh reported findings."
60
  fi
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  log "Starting OpenClaw Gateway directly on 0.0.0.0:7860."
63
- log "Nginx is intentionally not started: Hugging Face routes app_port 7860 directly to Gateway."
64
 
65
- # Restart Gateway if the process exits, but never mutate state/pairing files.
66
  while :; do
67
- if openclaw gateway --bind lan --port 7860; then
68
- rc=0
 
 
69
  else
70
- rc=$?
71
  fi
72
- log "Gateway exited with code $rc; retrying in 5 seconds."
 
 
 
 
 
 
 
73
  sleep 5
74
  done
 
7
  log() { echo "[$(ts)] [entrypoint] $*"; }
8
  die() { log "FATAL: $*"; exit 1; }
9
 
10
+ # Telegram Long Polling prefers IPv4 on HF runtimes with limited IPv6 egress.
 
11
  export NODE_OPTIONS="--dns-result-order=ipv4first ${NODE_OPTIONS:-}"
12
 
13
+ # Persistent Storage Bucket is mandatory; never silently fall back to ephemeral disk.
 
14
  [ -d /data ] || die "/data does not exist. Attach a persistent Storage Bucket to this Space."
15
  touch /data/.openclaw-write-test 2>/dev/null || die "/data is not writable."
16
  rm -f /data/.openclaw-write-test
17
 
18
  mkdir -p /data/.openclaw /home/user/.openclaw
19
 
20
+ # One-time migration only when the Bucket state directory is completely empty.
21
  if [ -z "$(find /data/.openclaw -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null)" ] \
22
  && [ -n "$(find /home/user/.openclaw -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null)" ]; then
23
  log "Bucket state is empty; migrating existing /home/user/.openclaw data."
 
30
  log "OPENCLAW_HOME=$OPENCLAW_HOME"
31
  log "Gateway public port=$OPENCLAW_GATEWAY_PORT"
32
 
33
+ # Fail closed if the config writer fails.
34
  log "Writing OpenClaw configuration..."
35
  node /app/spaces/huggingface/setup-hf-config.mjs \
36
  || die "setup-hf-config.mjs failed; Gateway will not be started."
 
38
  CONFIG=/data/.openclaw/openclaw.json
39
  [ -s "$CONFIG" ] || die "Configuration file was not created: $CONFIG"
40
 
41
+ # IMPORTANT: Do NOT run 'openclaw doctor --fix' on every container boot.
42
+ # Doctor requires exclusive maintenance ownership. A live Gateway/other process
43
+ # using this same state directory keeps that ownership and correctly blocks Doctor.
44
+ # Run Doctor manually only after stopping every Gateway using this Bucket.
45
+ log "Skipping automatic doctor --fix (maintenance requires exclusive state ownership)."
 
 
 
 
 
46
 
47
+ # Plugins must not be group/world writable.
48
  chmod -R go-w /data/.openclaw/npm /data/.openclaw/extensions 2>/dev/null || true
49
 
50
  if [ -f /app/security-check.sh ]; then
 
52
  sh /app/security-check.sh || log "WARNING: security-check.sh reported findings."
53
  fi
54
 
55
+ # Read-only process inventory. This does not modify lock, database, or pairing files.
56
+ log "Checking for other OpenClaw processes before Gateway startup..."
57
+ node --input-type=module - <<'NODE'
58
+ import fs from 'node:fs';
59
+ for (const pid of fs.readdirSync('/proc').filter((x) => /^\d+$/.test(x))) {
60
+ try {
61
+ const cmd = fs.readFileSync(`/proc/${pid}/cmdline`, 'utf8').replace(/\0/g, ' ').trim();
62
+ if (/openclaw|gateway\.(mjs|js)|dist\/entry\.js/.test(cmd)) {
63
+ console.log(`[process-check] pid=${pid} cmd=${cmd.slice(0, 260)}`);
64
+ }
65
+ } catch {}
66
+ }
67
+ NODE
68
+
69
  log "Starting OpenClaw Gateway directly on 0.0.0.0:7860."
70
+ log "Nginx is intentionally not started; Hugging Face app_port must be 7860."
71
 
 
72
  while :; do
73
+ GATEWAY_LOG=/tmp/openclaw-gateway.log
74
+ : > "$GATEWAY_LOG"
75
+ if openclaw gateway --bind lan --port 7860 >"$GATEWAY_LOG" 2>&1; then
76
+ GATEWAY_RC=0
77
  else
78
+ GATEWAY_RC=$?
79
  fi
80
+ cat "$GATEWAY_LOG"
81
+ log "Gateway exited with code $GATEWAY_RC."
82
+
83
+ if grep -Eqi 'GatewayLockError|failed to acquire gateway state ownership|another OpenClaw process owns|EADDRINUSE' "$GATEWAY_LOG"; then
84
+ die "Gateway state/port is already owned. Stop the other Gateway or detach this Bucket from other running Spaces; do not delete lock files."
85
+ fi
86
+
87
+ log "Unexpected Gateway exit; retrying in 5 seconds."
88
  sleep 5
89
  done