tao-shen Claude Opus 4.6 commited on
Commit
a065584
Β·
1 Parent(s): 7da6a48

fix: redirect all log output to stdout so HF runtime log API captures it

Browse files

HF's SSE log API only captures stdout, not stderr. All our scripts were
writing to stderr (>&2, file=sys.stderr). Added exec 2>&1 at top of
shell scripts and changed Python log() to write to stdout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

scripts/entrypoint.sh CHANGED
@@ -6,23 +6,25 @@
6
  # 3. Start sync-loop daemon in BACKGROUND
7
  # ─────────────────────────────────────────────────────────────────────
8
  set -e
9
- echo "========================================" >&2
10
- echo "[entrypoint] HuggingRun starting ..." >&2
11
- echo "[entrypoint] Date: $(date -u)" >&2
12
- echo "[entrypoint] SPACE_ID=${SPACE_ID:-not set}" >&2
13
- echo "[entrypoint] HF_TOKEN=${HF_TOKEN:+set (${#HF_TOKEN} chars)}${HF_TOKEN:-NOT SET}" >&2
14
- echo "[entrypoint] HF_DATASET_REPO=${HF_DATASET_REPO:-not set}" >&2
15
- echo "[entrypoint] PERSIST_PATH=${PERSIST_PATH:-/data}" >&2
16
- echo "[entrypoint] RUN_CMD=${RUN_CMD:-default}" >&2
17
- echo "========================================" >&2
 
 
18
 
19
  # Determine dataset repo
20
  if [ -z "$HF_DATASET_REPO" ]; then
21
  if [ -n "$SPACE_ID" ]; then
22
  export HF_DATASET_REPO="${SPACE_ID}-data"
23
- echo "[entrypoint] Auto-set HF_DATASET_REPO=${HF_DATASET_REPO}" >&2
24
  elif [ -n "$HF_TOKEN" ]; then
25
- echo "[entrypoint] Resolving HF_DATASET_REPO from token ..." >&2
26
  export HF_DATASET_REPO=$(python3 -c "
27
  from huggingface_hub import HfApi
28
  import os
@@ -32,13 +34,13 @@ try:
32
  except:
33
  print('')
34
  " 2>/dev/null)
35
- echo "[entrypoint] Resolved: ${HF_DATASET_REPO}" >&2
36
  fi
37
  fi
38
 
39
  # Ensure dataset repo exists
40
  if [ -n "$HF_TOKEN" ] && [ -n "$HF_DATASET_REPO" ]; then
41
- echo "[entrypoint] Verifying dataset: ${HF_DATASET_REPO} ..." >&2
42
  python3 -c "
43
  from huggingface_hub import HfApi
44
  import os
@@ -50,9 +52,9 @@ try:
50
  except:
51
  api.create_repo(repo_id=repo, repo_type='dataset', private=True)
52
  print(f'[entrypoint] Created dataset: {repo}', flush=True)
53
- " 2>&1 || echo "[entrypoint] WARNING: Could not verify dataset" >&2
54
  else
55
- echo "[entrypoint] WARNING: persistence disabled (no token/repo)" >&2
56
  fi
57
 
58
  # Write env for other processes
@@ -61,21 +63,21 @@ export HF_TOKEN="${HF_TOKEN}"
61
  export HF_DATASET_REPO="${HF_DATASET_REPO}"
62
  export PERSIST_PATH="${PERSIST_PATH:-/data}"
63
  ENVEOF
64
- echo "[entrypoint] Wrote /etc/huggingrun.env" >&2
65
 
66
  # Background: init (download + restore) then start sync-loop
67
  # This runs AFTER services start so HF doesn't timeout
68
  (
69
- echo "[entrypoint:bg] Starting init in background ..." >&2
70
  python3 -u /opt/git_sync_daemon.py init
71
- echo "[entrypoint:bg] Init done, starting sync-loop ..." >&2
72
  exec python3 -u /opt/git_sync_daemon.py sync-loop
73
  ) &
74
  BG_PID=$!
75
- echo "[entrypoint] Background init+sync PID=${BG_PID}" >&2
76
 
77
  # Start services immediately (so HF sees port 7860)
78
  CMD="${RUN_CMD:-python3 /app/demo_app.py}"
79
- echo "[entrypoint] Starting services: ${CMD}" >&2
80
- echo "========================================" >&2
81
  exec $CMD
 
6
  # 3. Start sync-loop daemon in BACKGROUND
7
  # ─────────────────────────────────────────────────────────────────────
8
  set -e
9
+ # Merge stderr β†’ stdout so HF runtime log API captures ALL output
10
+ exec 2>&1
11
+ echo "========================================"
12
+ echo "[entrypoint] HuggingRun starting ..."
13
+ echo "[entrypoint] Date: $(date -u)"
14
+ echo "[entrypoint] SPACE_ID=${SPACE_ID:-not set}"
15
+ echo "[entrypoint] HF_TOKEN=${HF_TOKEN:+set (${#HF_TOKEN} chars)}${HF_TOKEN:-NOT SET}"
16
+ echo "[entrypoint] HF_DATASET_REPO=${HF_DATASET_REPO:-not set}"
17
+ echo "[entrypoint] PERSIST_PATH=${PERSIST_PATH:-/data}"
18
+ echo "[entrypoint] RUN_CMD=${RUN_CMD:-default}"
19
+ echo "========================================"
20
 
21
  # Determine dataset repo
22
  if [ -z "$HF_DATASET_REPO" ]; then
23
  if [ -n "$SPACE_ID" ]; then
24
  export HF_DATASET_REPO="${SPACE_ID}-data"
25
+ echo "[entrypoint] Auto-set HF_DATASET_REPO=${HF_DATASET_REPO}"
26
  elif [ -n "$HF_TOKEN" ]; then
27
+ echo "[entrypoint] Resolving HF_DATASET_REPO from token ..."
28
  export HF_DATASET_REPO=$(python3 -c "
29
  from huggingface_hub import HfApi
30
  import os
 
34
  except:
35
  print('')
36
  " 2>/dev/null)
37
+ echo "[entrypoint] Resolved: ${HF_DATASET_REPO}"
38
  fi
39
  fi
40
 
41
  # Ensure dataset repo exists
42
  if [ -n "$HF_TOKEN" ] && [ -n "$HF_DATASET_REPO" ]; then
43
+ echo "[entrypoint] Verifying dataset: ${HF_DATASET_REPO} ..."
44
  python3 -c "
45
  from huggingface_hub import HfApi
46
  import os
 
52
  except:
53
  api.create_repo(repo_id=repo, repo_type='dataset', private=True)
54
  print(f'[entrypoint] Created dataset: {repo}', flush=True)
55
+ " 2>&1 || echo "[entrypoint] WARNING: Could not verify dataset"
56
  else
57
+ echo "[entrypoint] WARNING: persistence disabled (no token/repo)"
58
  fi
59
 
60
  # Write env for other processes
 
63
  export HF_DATASET_REPO="${HF_DATASET_REPO}"
64
  export PERSIST_PATH="${PERSIST_PATH:-/data}"
65
  ENVEOF
66
+ echo "[entrypoint] Wrote /etc/huggingrun.env"
67
 
68
  # Background: init (download + restore) then start sync-loop
69
  # This runs AFTER services start so HF doesn't timeout
70
  (
71
+ echo "[entrypoint:bg] Starting init in background ..."
72
  python3 -u /opt/git_sync_daemon.py init
73
+ echo "[entrypoint:bg] Init done, starting sync-loop ..."
74
  exec python3 -u /opt/git_sync_daemon.py sync-loop
75
  ) &
76
  BG_PID=$!
77
+ echo "[entrypoint] Background init+sync PID=${BG_PID}"
78
 
79
  # Start services immediately (so HF sees port 7860)
80
  CMD="${RUN_CMD:-python3 /app/demo_app.py}"
81
+ echo "[entrypoint] Starting services: ${CMD}"
82
+ echo "========================================"
83
  exec $CMD
ubuntu-server/git_sync_daemon.py CHANGED
@@ -43,7 +43,7 @@ UPLOAD_IGNORE = [
43
 
44
  def log(msg):
45
  ts = time.strftime("%H:%M:%S", time.gmtime())
46
- print(f"[sync {ts}] {msg}", file=sys.stderr, flush=True)
47
 
48
 
49
  def run(cmd, cwd=None):
@@ -271,7 +271,7 @@ def cmd_sync_loop():
271
  except Exception as e:
272
  log(f" βœ— Sync cycle #{cycle} error: {e}")
273
  import traceback
274
- traceback.print_exc(file=sys.stderr)
275
  log(f" Sleeping {SYNC_INTERVAL}s until next cycle ...")
276
  time.sleep(SYNC_INTERVAL)
277
 
 
43
 
44
  def log(msg):
45
  ts = time.strftime("%H:%M:%S", time.gmtime())
46
+ print(f"[sync {ts}] {msg}", flush=True)
47
 
48
 
49
  def run(cmd, cwd=None):
 
271
  except Exception as e:
272
  log(f" βœ— Sync cycle #{cycle} error: {e}")
273
  import traceback
274
+ traceback.print_exc(file=sys.stdout)
275
  log(f" Sleeping {SYNC_INTERVAL}s until next cycle ...")
276
  time.sleep(SYNC_INTERVAL)
277
 
ubuntu-server/start-server.sh CHANGED
@@ -4,28 +4,31 @@
4
  # Port 7860 (nginx): web terminal + SSH
5
  # ─────────────────────────────────────────────────────────────────────
6
 
 
 
 
7
  export SSH_PORT="${SSH_PORT:-2222}"
8
  export TTYD_PORT="${TTYD_PORT:-7681}"
9
 
10
- echo "========================================" >&2
11
- echo "[ubuntu] HuggingRun Ubuntu Server" >&2
12
- echo "[ubuntu] $(date -u)" >&2
13
- echo "[ubuntu] Kernel: $(uname -r)" >&2
14
- echo "[ubuntu] Arch: $(uname -m)" >&2
15
- echo "[ubuntu] Hostname: $(hostname)" >&2
16
- echo "[ubuntu] CPU: $(nproc) cores" >&2
17
- echo "[ubuntu] Memory: $(free -h 2>/dev/null | awk '/Mem:/{print $2}' || echo 'unknown')" >&2
18
- echo "[ubuntu] Disk: $(df -h / 2>/dev/null | awk 'NR==2{print $2, "total,", $4, "free"}' || echo 'unknown')" >&2
19
- echo "[ubuntu] User: $(whoami) (uid=$(id -u))" >&2
20
- echo "========================================" >&2
21
 
22
  # ── Network info ───────────────────────────────────────────────────
23
- echo "[ubuntu] Network interfaces:" >&2
24
- ip -4 addr show 2>/dev/null | grep -E 'inet |^[0-9]' | sed 's/^/ /' >&2 || true
25
 
26
  # ── sshd ──────────────────────────────────────────────────────────
27
  mkdir -p /run/sshd
28
- echo "[ubuntu] Starting sshd on 127.0.0.1:${SSH_PORT} ..." >&2
29
  /usr/sbin/sshd -o "Port=$SSH_PORT" \
30
  -o "ListenAddress=127.0.0.1" \
31
  -o "PermitRootLogin=yes" \
@@ -36,51 +39,51 @@ echo "[ubuntu] Starting sshd on 127.0.0.1:${SSH_PORT} ..." >&2
36
  SSHD_PID=$!
37
  sleep 1
38
  if kill -0 $SSHD_PID 2>/dev/null; then
39
- echo "[ubuntu] [ OK ] sshd started (PID=${SSHD_PID})" >&2
40
  else
41
- echo "[ubuntu] [FAILED] sshd failed to start" >&2
42
  fi
43
 
44
  # ── WebSocket-to-SSH bridge ──────────────────────────────────────
45
- echo "[ubuntu] Starting WS-SSH bridge on 127.0.0.1:7862 ..." >&2
46
  python3 /opt/ws-ssh-bridge.py &
47
  BRIDGE_PID=$!
48
  sleep 1
49
  if kill -0 $BRIDGE_PID 2>/dev/null; then
50
- echo "[ubuntu] [ OK ] WS-SSH bridge started (PID=${BRIDGE_PID})" >&2
51
  else
52
- echo "[ubuntu] [FAILED] WS-SSH bridge failed to start" >&2
53
  fi
54
 
55
  # ── ttyd (web terminal) ─────────────────────────────────────────
56
- echo "[ubuntu] Starting ttyd on 127.0.0.1:${TTYD_PORT} ..." >&2
57
  ttyd --port "$TTYD_PORT" --writable --base-path / bash --login &
58
  TTYD_PID=$!
59
  sleep 1
60
  if kill -0 $TTYD_PID 2>/dev/null; then
61
- echo "[ubuntu] [ OK ] ttyd started (PID=${TTYD_PID})" >&2
62
  else
63
- echo "[ubuntu] [FAILED] ttyd failed to start" >&2
64
  fi
65
 
66
  # ── Process summary ──────────────────────────────────────────────
67
- echo "========================================" >&2
68
- echo "[ubuntu] Services:" >&2
69
- echo "[ubuntu] sshd PID=${SSHD_PID} 127.0.0.1:${SSH_PORT}" >&2
70
- echo "[ubuntu] ws-ssh-bridge PID=${BRIDGE_PID} 127.0.0.1:7862" >&2
71
- echo "[ubuntu] ttyd PID=${TTYD_PID} 127.0.0.1:${TTYD_PORT}" >&2
72
- echo "[ubuntu] nginx (foreground) 0.0.0.0:7860" >&2
73
- echo "========================================" >&2
74
 
75
  # ── Installed packages ───────────────────────────────────────────
76
- echo "[ubuntu] Base packages: $(wc -l < /etc/base-packages.list 2>/dev/null || echo '?')" >&2
77
- echo "[ubuntu] Current packages: $(dpkg-query -W -f='\n' 2>/dev/null | wc -l)" >&2
78
 
79
  # ── Running processes ────────────────────────────────────────────
80
- echo "[ubuntu] All processes:" >&2
81
- ps aux --no-headers 2>/dev/null | awk '{printf "[ubuntu] %-8s PID=%-6s %s\n", $1, $2, $11}' >&2 || true
82
 
83
  # ── nginx (foreground, port 7860) ────────────────────────────────
84
- echo "[ubuntu] Starting nginx on 0.0.0.0:7860 (foreground) ..." >&2
85
- echo "[ubuntu] ══ System ready ══" >&2
86
  exec nginx -g 'daemon off;'
 
4
  # Port 7860 (nginx): web terminal + SSH
5
  # ─────────────────────────────────────────────────────────────────────
6
 
7
+ # Merge stderr β†’ stdout so HF runtime log API captures ALL output
8
+ exec 2>&1
9
+
10
  export SSH_PORT="${SSH_PORT:-2222}"
11
  export TTYD_PORT="${TTYD_PORT:-7681}"
12
 
13
+ echo "========================================"
14
+ echo "[ubuntu] HuggingRun Ubuntu Server"
15
+ echo "[ubuntu] $(date -u)"
16
+ echo "[ubuntu] Kernel: $(uname -r)"
17
+ echo "[ubuntu] Arch: $(uname -m)"
18
+ echo "[ubuntu] Hostname: $(hostname)"
19
+ echo "[ubuntu] CPU: $(nproc) cores"
20
+ echo "[ubuntu] Memory: $(free -h 2>/dev/null | awk '/Mem:/{print $2}' || echo 'unknown')"
21
+ echo "[ubuntu] Disk: $(df -h / 2>/dev/null | awk 'NR==2{print $2, "total,", $4, "free"}' || echo 'unknown')"
22
+ echo "[ubuntu] User: $(whoami) (uid=$(id -u))"
23
+ echo "========================================"
24
 
25
  # ── Network info ───────────────────────────────────────────────────
26
+ echo "[ubuntu] Network interfaces:"
27
+ ip -4 addr show 2>/dev/null | grep -E 'inet |^[0-9]' | sed 's/^/ /' || true
28
 
29
  # ── sshd ──────────────────────────────────────────────────────────
30
  mkdir -p /run/sshd
31
+ echo "[ubuntu] Starting sshd on 127.0.0.1:${SSH_PORT} ..."
32
  /usr/sbin/sshd -o "Port=$SSH_PORT" \
33
  -o "ListenAddress=127.0.0.1" \
34
  -o "PermitRootLogin=yes" \
 
39
  SSHD_PID=$!
40
  sleep 1
41
  if kill -0 $SSHD_PID 2>/dev/null; then
42
+ echo "[ubuntu] [ OK ] sshd started (PID=${SSHD_PID})"
43
  else
44
+ echo "[ubuntu] [FAILED] sshd failed to start"
45
  fi
46
 
47
  # ── WebSocket-to-SSH bridge ──────────────────────────────────────
48
+ echo "[ubuntu] Starting WS-SSH bridge on 127.0.0.1:7862 ..."
49
  python3 /opt/ws-ssh-bridge.py &
50
  BRIDGE_PID=$!
51
  sleep 1
52
  if kill -0 $BRIDGE_PID 2>/dev/null; then
53
+ echo "[ubuntu] [ OK ] WS-SSH bridge started (PID=${BRIDGE_PID})"
54
  else
55
+ echo "[ubuntu] [FAILED] WS-SSH bridge failed to start"
56
  fi
57
 
58
  # ── ttyd (web terminal) ─────────────────────────────────────────
59
+ echo "[ubuntu] Starting ttyd on 127.0.0.1:${TTYD_PORT} ..."
60
  ttyd --port "$TTYD_PORT" --writable --base-path / bash --login &
61
  TTYD_PID=$!
62
  sleep 1
63
  if kill -0 $TTYD_PID 2>/dev/null; then
64
+ echo "[ubuntu] [ OK ] ttyd started (PID=${TTYD_PID})"
65
  else
66
+ echo "[ubuntu] [FAILED] ttyd failed to start"
67
  fi
68
 
69
  # ── Process summary ──────────────────────────────────────────────
70
+ echo "========================================"
71
+ echo "[ubuntu] Services:"
72
+ echo "[ubuntu] sshd PID=${SSHD_PID} 127.0.0.1:${SSH_PORT}"
73
+ echo "[ubuntu] ws-ssh-bridge PID=${BRIDGE_PID} 127.0.0.1:7862"
74
+ echo "[ubuntu] ttyd PID=${TTYD_PID} 127.0.0.1:${TTYD_PORT}"
75
+ echo "[ubuntu] nginx (foreground) 0.0.0.0:7860"
76
+ echo "========================================"
77
 
78
  # ── Installed packages ───────────────────────────────────────────
79
+ echo "[ubuntu] Base packages: $(wc -l < /etc/base-packages.list 2>/dev/null || echo '?')"
80
+ echo "[ubuntu] Current packages: $(dpkg-query -W -f='\n' 2>/dev/null | wc -l)"
81
 
82
  # ── Running processes ────────────────────────────────────────────
83
+ echo "[ubuntu] All processes:"
84
+ ps aux --no-headers 2>/dev/null | awk '{printf "[ubuntu] %-8s PID=%-6s %s\n", $1, $2, $11}' || true
85
 
86
  # ── nginx (foreground, port 7860) ────────────────────────────────
87
+ echo "[ubuntu] Starting nginx on 0.0.0.0:7860 (foreground) ..."
88
+ echo "[ubuntu] ══ System ready ══"
89
  exec nginx -g 'daemon off;'