echo8900 commited on
Commit
dd094e5
·
verified ·
1 Parent(s): ed9e164

Update entrypoint.sh

Browse files
Files changed (1) hide show
  1. entrypoint.sh +95 -63
entrypoint.sh CHANGED
@@ -1,31 +1,49 @@
1
  #!/bin/sh
2
-
3
  # OpenClaw HF Spaces - Production Entrypoint
4
- # Storage: HF Storage Bucket mounted at /data (100 GB, persists across restarts)
5
-
6
- # -- resolve writable home ----------------------------------------
7
-
 
 
 
 
 
 
 
 
 
 
8
  OPENCLAW_HOME=/home/user
9
  mkdir -p /home/user/.openclaw
10
 
11
- if [ -d /data ]; then
12
- if touch /data/.bucket-write-test 2>/dev/null; then
13
- rm -f /data/.bucket-write-test
 
 
14
  OPENCLAW_HOME=/data
15
  mkdir -p /data/.openclaw
16
- echo "[entrypoint] Storage bucket at /data is writable - using persistent storage"
17
- else
18
- echo "[entrypoint] WARNING: /data exists but is not writable - falling back to ephemeral /home/user"
19
  fi
20
- else
21
- echo "[entrypoint] WARNING: /data not found - bucket may not be mounted, using ephemeral /home/user"
 
 
 
 
 
 
 
22
  fi
23
 
24
  export OPENCLAW_HOME
25
- echo "[entrypoint] OPENCLAW_HOME=$OPENCLAW_HOME"
26
-
27
- # -- dynamic provider key export ----------------------------------
28
 
 
 
 
29
  for VAR in $(env | cut -d= -f1); do
30
  case "$VAR" in
31
  OPENCLAW_*|SPACE_*|SYSTEM_*|HF_*|NODE_*|npm_*) continue ;;
@@ -35,7 +53,7 @@ for VAR in $(env | cut -d= -f1); do
35
  VAL=$(printenv "$VAR" 2>/dev/null || true)
36
  if [ -n "$VAL" ]; then
37
  export "$VAR"
38
- echo "[entrypoint] exported: $VAR"
39
  fi
40
  ;;
41
  esac
@@ -43,27 +61,27 @@ done
43
 
44
  export HF_TOKEN="${HF_TOKEN:-}"
45
 
46
- # -- run setup (patch mode: preserves user settings) --------------
47
-
48
- echo "[entrypoint] Running setup..."
 
49
  node /app/spaces/huggingface/setup-hf-config.mjs || true
50
- echo "[entrypoint] Setup done."
51
-
52
- # -- security audit -----------------------------------------------
53
 
 
 
 
54
  if [ -f /app/security-check.sh ]; then
55
  sh /app/security-check.sh || true
56
  fi
57
 
58
- # -- auto-approve pending device pairings -------------------------
59
-
60
- # Sub-agents connecting as nodes require device pairing.
61
- # This loop detects pending pairing requests and approves them automatically.
62
-
63
  (
64
  DEVICES_DIR="$OPENCLAW_HOME/.openclaw/devices"
65
  mkdir -p "$DEVICES_DIR"
66
- echo "[auto-pair] Device auto-approval started"
67
  while true; do
68
  sleep 8
69
  PENDING="$DEVICES_DIR/pending.json"
@@ -71,63 +89,77 @@ fi
71
  if [ -f "$PENDING" ]; then
72
  node - << 'JSEOF'
73
  const fs = require('fs');
74
- const devDir = process.env.OPENCLAW_HOME + '/.openclaw/devices';
75
- const pendingPath = devDir + '/pending.json';
76
- const pairedPath = devDir + '/paired.json';
77
  try {
78
- const raw = fs.readFileSync(pendingPath, 'utf-8').trim();
79
  if (!raw || raw === '[]' || raw === '{}') process.exit(0);
80
  let pending = JSON.parse(raw);
81
  if (!Array.isArray(pending)) pending = Object.values(pending);
82
  if (pending.length === 0) process.exit(0);
83
  let paired = [];
84
- if (fs.existsSync(pairedPath)) {
85
- try { paired = JSON.parse(fs.readFileSync(pairedPath, 'utf-8')); } catch(e) {}
86
- }
87
  if (!Array.isArray(paired)) paired = [];
88
- const pairedIds = new Set(paired.map(function(d) { return d.id || d.deviceId || d.name; }));
89
- const toApprove = pending.filter(function(d) {
90
- return !pairedIds.has(d.id || d.deviceId || d.name);
91
- });
92
- if (toApprove.length > 0) {
93
- const approved = toApprove.map(function(d) {
94
- return Object.assign({}, d, { approved: true, approvedAt: new Date().toISOString() });
95
- });
96
- paired = paired.concat(approved);
97
- fs.writeFileSync(pairedPath, JSON.stringify(paired, null, 2));
98
- fs.writeFileSync(pendingPath, '[]');
99
- console.log('[auto-pair] Approved ' + toApprove.length + ' device(s)');
100
- }
101
  } catch(e) { /* ignore */ }
102
  JSEOF
103
  fi
104
  done
105
  ) &
106
 
107
- # -- gateway loop -------------------------------------------------
108
-
109
- # Gateway exits on config save (OpenClaw full process restart).
110
- # When OpenClaw restarts it spawns a child process then the parent exits.
111
- # We must wait for port 7860 to be free before starting a new instance.
 
 
 
 
 
 
 
 
112
 
113
- echo "[entrypoint] Starting gateway loop..."
114
  while true; do
115
- echo "[entrypoint] Gateway starting..."
 
116
  node /app/openclaw.mjs gateway \
117
  --allow-unconfigured \
118
  --bind lan \
119
  --port 7860
120
- EXIT_CODE=$?
121
- echo "[entrypoint] Gateway exited (code $EXIT_CODE) - waiting for port 7860 to clear..."
122
- WAIT=0
 
 
 
123
  while nc -z 127.0.0.1 7860 2>/dev/null; do
 
 
 
124
  sleep 2
125
- WAIT=$((WAIT+2))
126
- if [ $WAIT -ge 60 ]; then
127
- echo "[entrypoint] Port 7860 still in use after 60s - forcing restart anyway"
128
  break
129
  fi
130
  done
131
- echo "[entrypoint] Restarting gateway..."
 
 
 
 
132
  sleep 1
 
133
  done
 
1
  #!/bin/sh
 
2
  # OpenClaw HF Spaces - Production Entrypoint
3
+ # Storage: HF Storage Bucket at /data (100 GB persistent)
4
+
5
+ # ----------------------------------------------------------------
6
+ # Logging
7
+ # ----------------------------------------------------------------
8
+ ts() { date -u +"%H:%M:%S"; }
9
+ log() { echo "[$(ts)] [entrypoint] $*"; }
10
+ warn() { echo "[$(ts)] [entrypoint] WARN: $*"; }
11
+
12
+ # ----------------------------------------------------------------
13
+ # Storage: resolve OPENCLAW_HOME
14
+ # Prefer /data (HF Storage Bucket). Fall back to /home/user.
15
+ # Retry up to 5s in case the bucket mount is slightly delayed.
16
+ # ----------------------------------------------------------------
17
  OPENCLAW_HOME=/home/user
18
  mkdir -p /home/user/.openclaw
19
 
20
+ RETRIES=5
21
+ i=0
22
+ while [ $i -lt $RETRIES ]; do
23
+ if [ -d /data ] && touch /data/.write-test 2>/dev/null; then
24
+ rm -f /data/.write-test
25
  OPENCLAW_HOME=/data
26
  mkdir -p /data/.openclaw
27
+ log "Storage bucket /data is writable - using persistent storage"
28
+ break
 
29
  fi
30
+ i=$((i+1))
31
+ if [ $i -lt $RETRIES ]; then
32
+ log "Waiting for /data mount... ($i/$RETRIES)"
33
+ sleep 1
34
+ fi
35
+ done
36
+
37
+ if [ "$OPENCLAW_HOME" = "/home/user" ]; then
38
+ warn "/data not writable after ${RETRIES}s - using ephemeral /home/user"
39
  fi
40
 
41
  export OPENCLAW_HOME
42
+ log "OPENCLAW_HOME=$OPENCLAW_HOME"
 
 
43
 
44
+ # ----------------------------------------------------------------
45
+ # Export provider API keys from Secrets
46
+ # ----------------------------------------------------------------
47
  for VAR in $(env | cut -d= -f1); do
48
  case "$VAR" in
49
  OPENCLAW_*|SPACE_*|SYSTEM_*|HF_*|NODE_*|npm_*) continue ;;
 
53
  VAL=$(printenv "$VAR" 2>/dev/null || true)
54
  if [ -n "$VAL" ]; then
55
  export "$VAR"
56
+ log "exported: $VAR"
57
  fi
58
  ;;
59
  esac
 
61
 
62
  export HF_TOKEN="${HF_TOKEN:-}"
63
 
64
+ # ----------------------------------------------------------------
65
+ # One-time setup (config write, webhook registration, seed files)
66
+ # ----------------------------------------------------------------
67
+ log "Running setup..."
68
  node /app/spaces/huggingface/setup-hf-config.mjs || true
69
+ log "Setup done."
 
 
70
 
71
+ # ----------------------------------------------------------------
72
+ # Security audit (non-fatal)
73
+ # ----------------------------------------------------------------
74
  if [ -f /app/security-check.sh ]; then
75
  sh /app/security-check.sh || true
76
  fi
77
 
78
+ # ----------------------------------------------------------------
79
+ # Auto-approve pending device pairings (background)
80
+ # ----------------------------------------------------------------
 
 
81
  (
82
  DEVICES_DIR="$OPENCLAW_HOME/.openclaw/devices"
83
  mkdir -p "$DEVICES_DIR"
84
+ log "Device auto-pairing watcher started"
85
  while true; do
86
  sleep 8
87
  PENDING="$DEVICES_DIR/pending.json"
 
89
  if [ -f "$PENDING" ]; then
90
  node - << 'JSEOF'
91
  const fs = require('fs');
92
+ const dir = process.env.OPENCLAW_HOME + '/.openclaw/devices';
93
+ const pend = dir + '/pending.json';
94
+ const pair = dir + '/paired.json';
95
  try {
96
+ const raw = fs.readFileSync(pend, 'utf-8').trim();
97
  if (!raw || raw === '[]' || raw === '{}') process.exit(0);
98
  let pending = JSON.parse(raw);
99
  if (!Array.isArray(pending)) pending = Object.values(pending);
100
  if (pending.length === 0) process.exit(0);
101
  let paired = [];
102
+ try { paired = JSON.parse(fs.readFileSync(pair, 'utf-8')); } catch(e) {}
 
 
103
  if (!Array.isArray(paired)) paired = [];
104
+ const ids = new Set(paired.map(function(d){ return d.id||d.deviceId||d.name; }));
105
+ const todo = pending.filter(function(d){ return !ids.has(d.id||d.deviceId||d.name); });
106
+ if (todo.length === 0) process.exit(0);
107
+ const now = new Date().toISOString();
108
+ paired = paired.concat(todo.map(function(d){
109
+ return Object.assign({}, d, { approved: true, approvedAt: now });
110
+ }));
111
+ fs.writeFileSync(pair, JSON.stringify(paired, null, 2));
112
+ fs.writeFileSync(pend, '[]');
113
+ console.log('[auto-pair] Approved ' + todo.length + ' device(s)');
 
 
 
114
  } catch(e) { /* ignore */ }
115
  JSEOF
116
  fi
117
  done
118
  ) &
119
 
120
+ # ----------------------------------------------------------------
121
+ # Gateway loop
122
+ #
123
+ # OpenClaw restart behaviour:
124
+ # - On config save it spawns a child process (new gateway) then
125
+ # the parent exits with code 0.
126
+ # - The child inherits the port 7860 lock.
127
+ # - We must NOT restart until the child also exits (port is free).
128
+ #
129
+ # Normal crash: port is immediately free, loop restarts quickly.
130
+ # Config-save restart: port stays held by child; we wait up to 90s.
131
+ # ----------------------------------------------------------------
132
+ log "Starting gateway loop..."
133
 
 
134
  while true; do
135
+ log "Gateway starting..."
136
+
137
  node /app/openclaw.mjs gateway \
138
  --allow-unconfigured \
139
  --bind lan \
140
  --port 7860
141
+ CODE=$?
142
+
143
+ log "Gateway exited (code $CODE)"
144
+
145
+ # Wait for port 7860 to be released before starting a new instance
146
+ WAITED=0
147
  while nc -z 127.0.0.1 7860 2>/dev/null; do
148
+ if [ $WAITED -eq 0 ]; then
149
+ log "Port 7860 still held (spawned child running) - waiting..."
150
+ fi
151
  sleep 2
152
+ WAITED=$((WAITED + 2))
153
+ if [ $WAITED -ge 90 ]; then
154
+ warn "Port 7860 still in use after 90s - forcing restart"
155
  break
156
  fi
157
  done
158
+
159
+ if [ $WAITED -gt 0 ]; then
160
+ log "Port free after ${WAITED}s"
161
+ fi
162
+
163
  sleep 1
164
+ log "Restarting gateway..."
165
  done