Elysiadev11 commited on
Commit
035e36b
Β·
verified Β·
1 Parent(s): 9f7ba8d

Upload start-openclaw.sh with huggingface_hub

Browse files
Files changed (1) hide show
  1. start-openclaw.sh +141 -38
start-openclaw.sh CHANGED
@@ -1,12 +1,12 @@
1
  #!/bin/bash
2
 
3
  # ─────────────────────────────────────────────────────────────
4
- # πŸ“ PATH: start-openclaw.sh (root HF Space repo)
5
  # ─────────────────────────────────────────────────────────────
6
 
7
  set +e
8
 
9
- echo "===== OpenClaw Startup ====="
10
 
11
  # ── TRAP: Backup saat container mati ─────────────────────────
12
  trap 'echo ">>> [TRAP] Container stopping β€” final backup..."; python3 /app/sync.py backup; echo ">>> [TRAP] Done."' EXIT SIGTERM SIGINT
@@ -16,13 +16,15 @@ mkdir -p /root/.openclaw/agents/main/sessions
16
  mkdir -p /root/.openclaw/credentials
17
  mkdir -p /root/.openclaw/sessions
18
  mkdir -p /root/.openclaw/browsers
 
 
19
  echo ">>> Directories ready."
20
 
21
  # ── 2. Restore backup ─────────────────────────────────────────
22
  python3 /app/sync.py restore
23
  echo ">>> Restore done."
24
 
25
- # ── 3. Fix DNS (tanpa hosts override β€” apiRoot sudah handle) ─
26
  echo "nameserver 1.1.1.1" >> /etc/resolv.conf
27
  echo "nameserver 8.8.8.8" >> /etc/resolv.conf
28
  echo "nameserver 8.8.4.4" >> /etc/resolv.conf
@@ -53,7 +55,11 @@ CLEAN_BASE=$(echo "$OPENAI_API_BASE" \
53
 
54
  ALLOW_ID_SAFE=${TELEGRAM_ALLOW_ID:-0}
55
 
56
- # ── 6. Fungsi Auto-Fix JSON (Template Aman Kita) ──────────────
 
 
 
 
57
  generate_safe_json() {
58
  echo ">>> [AUTO-FIX] Menulis ulang openclaw.json ke pengaturan aman..."
59
  cat > /root/.openclaw/openclaw.json <<JSONEOF
@@ -149,7 +155,7 @@ generate_safe_json() {
149
  JSONEOF
150
  }
151
 
152
- # Cek integritas JSON di awal. Kalau valid dari backup, biarkan. Kalau rusak/kosong, timpa!
153
  echo ">>> Memeriksa integritas file openclaw.json..."
154
  if [ ! -f /root/.openclaw/openclaw.json ] || ! python3 -c 'import json; json.load(open("/root/.openclaw/openclaw.json"))' 2>/dev/null; then
155
  generate_safe_json
@@ -157,34 +163,76 @@ else
157
  echo ">>> File openclaw.json yang valid ditemukan (Editan AI aman dijaga)."
158
  fi
159
 
160
- # ── 7. Node.js reverse proxy (ANTI-TIMEOUT TRICK) ─────────────
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  node -e "
162
  const http = require('http');
163
  const net = require('net');
164
 
165
  process.on('uncaughtException', err => console.error('Proxy Exception:', err.message));
166
 
167
- function proxyHttp(req, res, targetPort) {
168
  const opts = {
169
- hostname: '127.0.0.1', port: targetPort,
170
- path: req.url, method: req.method,
171
- headers: req.headers,
 
 
172
  };
173
  const pr = http.request(opts, (r) => {
174
- res.writeHead(r.statusCode, r.headers);
 
 
 
 
 
 
 
 
 
 
175
  r.pipe(res, { end: true });
176
  });
177
  pr.on('error', (e) => {
178
- res.writeHead(200, { 'Content-Type': 'text/html' });
179
- res.end('<html style=\"background:#1e1e2e; color:#cdd6f4; font-family:sans-serif; text-align:center; padding-top:20%;\"><body><h2>πŸš€ OpenClaw is warming up...</h2><p>Please refresh in a few seconds.</p></body></html>');
 
 
 
 
 
180
  });
181
  req.pipe(pr, { end: true });
182
  }
183
 
184
- function proxyWs(req, socket, head, targetPort) {
185
  const conn = net.connect(targetPort, '127.0.0.1', () => {
 
186
  conn.write(
187
- 'GET ' + req.url + ' HTTP/1.1\r\n' +
188
  Object.entries(req.headers).map(([k,v]) => k+': '+v).join('\r\n') +
189
  '\r\n\r\n'
190
  );
@@ -197,19 +245,35 @@ function proxyWs(req, socket, head, targetPort) {
197
  }
198
 
199
  const server = http.createServer((req, res) => {
200
- const port = req.url.startsWith('/tg-webhook') ? 8787 : 7862;
201
- proxyHttp(req, res, port);
 
 
 
 
 
 
 
 
202
  });
 
203
  server.on('upgrade', (req, socket, head) => {
204
- proxyWs(req, socket, head, 7862);
 
 
 
 
 
 
205
  });
 
206
  server.listen(7860, '0.0.0.0', () => {
207
- console.log('Proxy on port 7860 | /tg-webhook β†’ 8787 | /* β†’ 7862');
208
  });
209
  " &
210
  echo ">>> Node.js reverse proxy started on port 7860."
211
 
212
- # ── 8. Backup otomatis setiap 1 Jam ──────────────────────────
213
  (
214
  sleep 60
215
  echo ">>> Initial backup (60s after startup)..."
@@ -222,42 +286,81 @@ echo ">>> Node.js reverse proxy started on port 7860."
222
  done
223
  ) &
224
 
225
- # ── 9. Jalankan OpenClaw (Cerdas & Auto-Healing) ──────────────
 
 
226
  RESTART_COUNT=0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  while true; do
228
  RESTART_COUNT=$((RESTART_COUNT + 1))
229
 
230
- echo ">>> Running openclaw doctor --fix..."
231
  openclaw doctor --fix
232
  DOC_EXIT=$?
233
 
234
- # Kalau doctor gagal memvalidasi karena editan AI ngaco, langsung auto-fix
235
  if [ $DOC_EXIT -ne 0 ]; then
236
- echo ">>> [WARNING] OpenClaw Doctor menemukan error fatal di config! Memulai auto-fix..."
237
  generate_safe_json
238
  openclaw doctor --fix
239
  fi
240
 
241
- echo ">>> [Loop #$RESTART_COUNT] Starting OpenClaw gateway on port 7862..."
242
 
243
- # LOG FILTER ULTIMATE: Membungkam segala jenis spam log dari Telegram
244
- openclaw gateway run --port 7862 2>&1 | grep --line-buffered -viE "pairing required|native approval handler|GatewayClientRequestError|security audit: device access upgrade requested"
245
-
246
- # Ambil exit code asli aplikasi (bukan dari grep)
247
- EXIT_CODE=${PIPESTATUS[0]}
248
 
249
- echo ">>> [Loop #$RESTART_COUNT] Gateway stopped (exit code: $EXIT_CODE)."
 
 
250
 
251
- # Cek penyebab berhentinya. Code 0 (sukses) atau 143 (di-restart manual) aman.
252
- # Kalau selain itu (misal Code 1 atau 78 karena crash/error), jalankan auto-fix!
253
- if [ "$EXIT_CODE" -ne 0 ] && [ "$EXIT_CODE" -ne 143 ]; then
254
- echo ">>> [CRITICAL] Gateway CRASH dengan exit code $EXIT_CODE! Mengembalikan config ke pengaturan aman..."
255
- generate_safe_json
256
- fi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
 
258
  echo ">>> Backing up..."
259
  python3 /app/sync.py backup
260
  echo ">>> Restarting gateway in 5 seconds..."
261
  sleep 5
262
  done
263
-
 
1
  #!/bin/bash
2
 
3
  # ─────────────────────────────────────────────────────────────
4
+ # start-openclaw.sh β€” OpenClaw + code-server + tmux
5
  # ─────────────────────────────────────────────────────────────
6
 
7
  set +e
8
 
9
+ echo "===== OpenClaw + VS Code Startup ====="
10
 
11
  # ── TRAP: Backup saat container mati ─────────────────────────
12
  trap 'echo ">>> [TRAP] Container stopping β€” final backup..."; python3 /app/sync.py backup; echo ">>> [TRAP] Done."' EXIT SIGTERM SIGINT
 
16
  mkdir -p /root/.openclaw/credentials
17
  mkdir -p /root/.openclaw/sessions
18
  mkdir -p /root/.openclaw/browsers
19
+ mkdir -p /home/coder/workspace
20
+ mkdir -p /root/.config/code-server
21
  echo ">>> Directories ready."
22
 
23
  # ── 2. Restore backup ─────────────────────────────────────────
24
  python3 /app/sync.py restore
25
  echo ">>> Restore done."
26
 
27
+ # ── 3. Fix DNS ────────────────────────────────────────────────
28
  echo "nameserver 1.1.1.1" >> /etc/resolv.conf
29
  echo "nameserver 8.8.8.8" >> /etc/resolv.conf
30
  echo "nameserver 8.8.4.4" >> /etc/resolv.conf
 
55
 
56
  ALLOW_ID_SAFE=${TELEGRAM_ALLOW_ID:-0}
57
 
58
+ # ── 6. Password untuk code-server & gateway ──────────────────
59
+ VSCODE_PASSWORD="${OPENCLAW_GATEWAY_PASSWORD:-openclaw}"
60
+ echo ">>> code-server password set from OPENCLAW_GATEWAY_PASSWORD"
61
+
62
+ # ── 7. Fungsi Auto-Fix JSON ──────────────────────────────────
63
  generate_safe_json() {
64
  echo ">>> [AUTO-FIX] Menulis ulang openclaw.json ke pengaturan aman..."
65
  cat > /root/.openclaw/openclaw.json <<JSONEOF
 
155
  JSONEOF
156
  }
157
 
158
+ # Cek integritas JSON di awal
159
  echo ">>> Memeriksa integritas file openclaw.json..."
160
  if [ ! -f /root/.openclaw/openclaw.json ] || ! python3 -c 'import json; json.load(open("/root/.openclaw/openclaw.json"))' 2>/dev/null; then
161
  generate_safe_json
 
163
  echo ">>> File openclaw.json yang valid ditemukan (Editan AI aman dijaga)."
164
  fi
165
 
166
+ # ── 8. Start code-server ─────────────────────────────────────
167
+ echo ">>> Starting code-server on port 8443..."
168
+
169
+ # Write code-server config
170
+ cat > /root/.config/code-server/config.yaml <<EOF
171
+ bind-addr: 0.0.0.0:8443
172
+ auth: password
173
+ password: ${VSCODE_PASSWORD}
174
+ cert: false
175
+ EOF
176
+
177
+ # Start code-server in background
178
+ code-server --bind-addr 0.0.0.0:8443 \
179
+ --auth password \
180
+ --disable-telemetry \
181
+ --disable-update-check \
182
+ /home/coder/workspace &
183
+ CODE_SERVER_PID=$!
184
+ echo ">>> code-server started (PID: $CODE_SERVER_PID)"
185
+
186
+ # ── 9. Node.js reverse proxy (port 7860) ─────────────────────
187
+ # /code/* β†’ code-server :8443 (strip /code prefix)
188
+ # /tg-webhook β†’ telegram :8787
189
+ # /* β†’ openclaw :7862
190
+ # ─────────────────────────────────────────────────────────────
191
  node -e "
192
  const http = require('http');
193
  const net = require('net');
194
 
195
  process.on('uncaughtException', err => console.error('Proxy Exception:', err.message));
196
 
197
+ function proxyHttp(req, res, targetPort, rewritePath) {
198
  const opts = {
199
+ hostname: '127.0.0.1',
200
+ port: targetPort,
201
+ path: rewritePath || req.url,
202
+ method: req.method,
203
+ headers: { ...req.headers, host: req.headers.host },
204
  };
205
  const pr = http.request(opts, (r) => {
206
+ // For code-server: rewrite Location headers
207
+ const headers = { ...r.headers };
208
+ if (targetPort === 8443 && headers.location) {
209
+ // If code-server redirects to /, make it /code/
210
+ if (headers.location === '/' || headers.location === '') {
211
+ headers.location = '/code/';
212
+ } else if (!headers.location.startsWith('/code') && headers.location.startsWith('/')) {
213
+ headers.location = '/code' + headers.location;
214
+ }
215
+ }
216
+ res.writeHead(r.statusCode, headers);
217
  r.pipe(res, { end: true });
218
  });
219
  pr.on('error', (e) => {
220
+ if (targetPort === 8443) {
221
+ res.writeHead(200, { 'Content-Type': 'text/html' });
222
+ res.end('<html style=\"background:#1e1e2e;color:#cdd6f4;font-family:sans-serif;text-align:center;padding-top:20%\"><body><h2>VS Code is starting up...</h2><p>Please refresh in a few seconds.</p></body></html>');
223
+ } else {
224
+ res.writeHead(200, { 'Content-Type': 'text/html' });
225
+ res.end('<html style=\"background:#1e1e2e;color:#cdd6f4;font-family:sans-serif;text-align:center;padding-top:20%\"><body><h2>OpenClaw is warming up...</h2><p>Please refresh in a few seconds.</p></body></html>');
226
+ }
227
  });
228
  req.pipe(pr, { end: true });
229
  }
230
 
231
+ function proxyWs(req, socket, head, targetPort, rewritePath) {
232
  const conn = net.connect(targetPort, '127.0.0.1', () => {
233
+ const path = rewritePath || req.url;
234
  conn.write(
235
+ 'GET ' + path + ' HTTP/1.1\r\n' +
236
  Object.entries(req.headers).map(([k,v]) => k+': '+v).join('\r\n') +
237
  '\r\n\r\n'
238
  );
 
245
  }
246
 
247
  const server = http.createServer((req, res) => {
248
+ if (req.url.startsWith('/code')) {
249
+ // Strip /code prefix for code-server
250
+ let newPath = req.url.replace(/^\/code\/?/, '/');
251
+ if (newPath === '') newPath = '/';
252
+ proxyHttp(req, res, 8443, newPath);
253
+ } else if (req.url.startsWith('/tg-webhook')) {
254
+ proxyHttp(req, res, 8787);
255
+ } else {
256
+ proxyHttp(req, res, 7862);
257
+ }
258
  });
259
+
260
  server.on('upgrade', (req, socket, head) => {
261
+ if (req.url.startsWith('/code')) {
262
+ let newPath = req.url.replace(/^\/code\/?/, '/');
263
+ if (newPath === '') newPath = '/';
264
+ proxyWs(req, socket, head, 8443, newPath);
265
+ } else {
266
+ proxyWs(req, socket, head, 7862);
267
+ }
268
  });
269
+
270
  server.listen(7860, '0.0.0.0', () => {
271
+ console.log('Proxy on port 7860 | /code/* -> 8443 | /tg-webhook -> 8787 | /* -> 7862');
272
  });
273
  " &
274
  echo ">>> Node.js reverse proxy started on port 7860."
275
 
276
+ # ── 10. Backup otomatis setiap 1 Jam ─────────────────────────
277
  (
278
  sleep 60
279
  echo ">>> Initial backup (60s after startup)..."
 
286
  done
287
  ) &
288
 
289
+ # ── 11. Jalankan OpenClaw di tmux session ─────────────────────
290
+ # User bisa attach dari VS Code terminal: tmux attach -t openclaw
291
+ # ─────────────────────────────────────────────────────────────
292
  RESTART_COUNT=0
293
+
294
+ # Create a helper script yang dipanggil di dalam tmux
295
+ cat > /app/run-openclaw.sh <<'RUNCLAW'
296
+ #!/bin/bash
297
+ set +e
298
+
299
+ echo ">>> Running openclaw doctor --fix..."
300
+ openclaw doctor --fix
301
+ DOC_EXIT=$?
302
+
303
+ if [ $DOC_EXIT -ne 0 ]; then
304
+ echo ">>> [WARNING] Doctor found fatal errors! Config will be regenerated on next restart."
305
+ fi
306
+
307
+ echo ">>> Starting OpenClaw gateway on port 7862..."
308
+ exec openclaw gateway run --port 7862 2>&1 | grep --line-buffered -viE "pairing required|native approval handler|GatewayClientRequestError|security audit: device access upgrade requested"
309
+ RUNCLAW
310
+ chmod +x /app/run-openclaw.sh
311
+
312
+ # Main loop: run OpenClaw in tmux, restart on crash
313
  while true; do
314
  RESTART_COUNT=$((RESTART_COUNT + 1))
315
 
316
+ echo ">>> [Loop #$RESTART_COUNT] Running openclaw doctor --fix..."
317
  openclaw doctor --fix
318
  DOC_EXIT=$?
319
 
320
+ # Kalau doctor gagal, auto-fix config
321
  if [ $DOC_EXIT -ne 0 ]; then
322
+ echo ">>> [WARNING] OpenClaw Doctor menemukan error fatal! Auto-fix..."
323
  generate_safe_json
324
  openclaw doctor --fix
325
  fi
326
 
327
+ echo ">>> [Loop #$RESTART_COUNT] Starting OpenClaw gateway in tmux session 'openclaw'..."
328
 
329
+ # Kill existing tmux session if any
330
+ tmux kill-session -t openclaw 2>/dev/null || true
 
 
 
331
 
332
+ # Start OpenClaw inside tmux session
333
+ tmux new-session -d -s openclaw -x 200 -y 50 \
334
+ "openclaw gateway run --port 7862 2>&1 | grep --line-buffered -viE 'pairing required|native approval handler|GatewayClientRequestError|security audit: device access upgrade requested'; echo '>>> OpenClaw exited. Session will stay open.'; sleep infinity"
335
 
336
+ echo ">>> OpenClaw running in tmux session 'openclaw'"
337
+ echo ">>> Attach from VS Code terminal: tmux attach -t openclaw"
338
+
339
+ # Monitor the tmux session - wait until openclaw process dies
340
+ while true; do
341
+ sleep 10
342
+
343
+ # Check if openclaw gateway process is still running
344
+ if ! pgrep -f "openclaw gateway" > /dev/null 2>&1; then
345
+ echo ">>> [Loop #$RESTART_COUNT] OpenClaw gateway process died!"
346
+ break
347
+ fi
348
+
349
+ # Also check if tmux session still exists
350
+ if ! tmux has-session -t openclaw 2>/dev/null; then
351
+ echo ">>> [Loop #$RESTART_COUNT] tmux session 'openclaw' ended!"
352
+ break
353
+ fi
354
+ done
355
+
356
+ echo ">>> [Loop #$RESTART_COUNT] Gateway stopped."
357
+
358
+ # Auto-fix config on crash
359
+ echo ">>> [CRITICAL] Gateway crashed! Restoring safe config..."
360
+ generate_safe_json
361
 
362
  echo ">>> Backing up..."
363
  python3 /app/sync.py backup
364
  echo ">>> Restarting gateway in 5 seconds..."
365
  sleep 5
366
  done