File size: 2,305 Bytes
e66e94d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/bin/bash
# Keeps OmniRoute's SQLite state alive across Space restarts/sleeps by
# syncing /app/data to a private HuggingFace Dataset repo.
#
# Required Space secrets (Settings β†’ Variables and secrets):
#   HF_TOKEN          β€” a HF token with WRITE access to the dataset below
#   HF_STATE_DATASET   β€” e.g. "your-username/omniroute-state" (make it PRIVATE β€”
#                        it will contain encrypted provider keys)
#   JWT_SECRET, API_KEY_SECRET, STORAGE_ENCRYPTION_KEY, INITIAL_PASSWORD
#                       β€” same as any other OmniRoute deployment

set -u
DATA_DIR=/app/data
mkdir -p "$DATA_DIR"

: "${HF_TOKEN:?Set HF_TOKEN as a Space secret}"
: "${HF_STATE_DATASET:?Set HF_STATE_DATASET as a Space secret, e.g. you/omniroute-state}"

echo "[sync] attempting to restore prior state from ${HF_STATE_DATASET}..."
python3 - <<PYEOF || echo "[sync] no snapshot found β€” starting fresh"
import os, shutil
from huggingface_hub import snapshot_download

path = snapshot_download(
    repo_id="${HF_STATE_DATASET}",
    repo_type="dataset",
    token="${HF_TOKEN}",
)
for item in os.listdir(path):
    if item.startswith("."):
        continue
    src = os.path.join(path, item)
    dst = os.path.join("${DATA_DIR}", item)
    if os.path.isfile(src):
        shutil.copy2(src, dst)
        print(f"[sync] restored {item}")
PYEOF

push_state() {
  python3 - <<PYEOF
from huggingface_hub import HfApi
api = HfApi(token="${HF_TOKEN}")
api.upload_folder(
    folder_path="${DATA_DIR}",
    repo_id="${HF_STATE_DATASET}",
    repo_type="dataset",
    commit_message="omniroute state sync",
)
PYEOF
}

# Push state every 5 minutes so a sudden restart loses at most that much.
(
  while true; do
    sleep 300
    echo "[sync] periodic push..."
    push_state || echo "[sync] periodic push failed, will retry next cycle"
  done
) &
SYNC_PID=$!

# Best-effort final push if the container gets a graceful stop signal.
trap 'echo "[sync] shutdown signal β€” final push"; push_state || true; kill $SYNC_PID 2>/dev/null; exit 0' SIGTERM SIGINT

# Hand off to the image's normal server process (Next.js standalone server β€”
# this is the base image's own default CMD, reproduced here explicitly
# since our CMD override replaced it).
node dev/run-standalone.mjs &
SERVER_PID=$!
wait "$SERVER_PID"