#!/bin/bash # Ensure HF CLI is in PATH export PATH="$HOME/.local/bin:$PATH" # Set HF Token from Space Secrets export HF_TOKEN="${HF_TOKEN}" # Variables BUCKET='hf://buckets/jerecom/Opencod-storage' SOURCE='/home' # Configure Git git config --global user.email 'badal@example.com' git config --global user.name 'Badal' # Set OpenCode path OP_PATH=$(find / -name opencode -type f -printf '%h' -quit 2>/dev/null) export PATH="$OP_PATH:$PATH" # ============================================ # STEP 0: BUCKET CLEANUP (Delete .cache & .npm from bucket) # ============================================ echo '=== [STEP 0] CLEANING BUCKET (Removing .cache and .npm) ===' hf buckets rm "$BUCKET/.cache" --recursive -y 2>/dev/null && echo '=== [STEP 0] .cache removed from bucket ===' || echo '=== [STEP 0] .cache not found in bucket (skipping) ===' hf buckets rm "$BUCKET/.npm" --recursive -y 2>/dev/null && echo '=== [STEP 0] .npm removed from bucket ===' || echo '=== [STEP 0] .npm not found in bucket (skipping) ===' echo '=== [STEP 0] BUCKET CLEANUP DONE ===' # ============================================ # STEP 1: RESTORE (Try, but continue if bucket empty) # ============================================ echo '=== [STEP 1] RESTORING DATA FROM BUCKET ===' if hf sync "$BUCKET" "$SOURCE" --delete 2>/dev/null; then echo '=== [STEP 1] RESTORE COMPLETE ===' else echo '=== [STEP 1] Restore skipped (bucket empty or failed - continuing anyway) ===' fi # Auto-create /home/user if not exists if [ ! -d "/home/user" ]; then echo '=== Creating /home/user folder ===' mkdir -p /home/user fi # ============================================ # STEP 2: START OPENCODE (with RAM watchdog) # ============================================ # RAM limit: 14GB in KB RAM_LIMIT_KB=$((14 * 1024 * 1024)) start_opencode() { echo '=== [STEP 2] STARTING OPENCODE ===' export OPENCODE_SERVER_USERNAME=${OPENCODE_SERVER_USERNAME} export OPENCODE_SERVER_PASSWORD=${OPENCODE_SERVER_PASSWORD} opencode web --port 7860 --hostname 0.0.0.0 > /tmp/opencode.log 2>&1 & OPENCODE_PID=$! echo "=== [STEP 2] OPENCODE STARTED (PID: $OPENCODE_PID) ===" } ram_watchdog() { while true; do if [ -n "$OPENCODE_PID" ] && kill -0 "$OPENCODE_PID" 2>/dev/null; then # OpenCode + uske saare child processes ki total RAM (KB) USED_KB=$(ps --no-headers -o rss --ppid "$OPENCODE_PID" 2>/dev/null | awk '{sum+=$1} END {print sum+0}') SELF_KB=$(ps --no-headers -o rss -p "$OPENCODE_PID" 2>/dev/null | awk '{print $1+0}') TOTAL_KB=$((USED_KB + SELF_KB)) #echo "=== [RAM] OpenCode using: $((TOTAL_KB / 1024))MB / 14336MB ===" if [ "$TOTAL_KB" -ge "$RAM_LIMIT_KB" ]; then echo "=== [RAM] LIMIT EXCEEDED! Killing OpenCode (${TOTAL_KB}KB >= ${RAM_LIMIT_KB}KB) ===" kill -9 "$OPENCODE_PID" 2>/dev/null sleep 3 echo '=== [RAM] Restarting OpenCode... ===' start_opencode fi else # OpenCode kisi aur wajah se mar gaya — restart echo '=== [RAM] OpenCode not running! Restarting... ===' start_opencode fi done } start_opencode sleep 10 # RAM watchdog background mein chalao ram_watchdog & # ============================================ # STEP 3: INOTIFY TRIGGER + 30s DEBOUNCE SYNC # ============================================ echo '=== [STEP 3] STARTING SMART SYNC (inotify + 30s debounce) ===' do_sync() { echo "=== [STEP 3] Syncing to bucket... ===" hf sync "$SOURCE" "$BUCKET" --delete \ --exclude "*.mdb" \ --exclude "*.log" \ --exclude ".cache" \ --exclude ".npm" \ --exclude ".check_for_update_done" \ --exclude "rg" echo "=== [STEP 3] Sync done! ===" } LAST_SYNC=0 while true; do # Check if OpenCode is still running if ! pgrep -f 'opencode' > /dev/null; then echo 'CRITICAL: OpenCode process died! Exiting container...' exit 1 fi # Wait for ANY change — modify, create, delete, move, rename, attrib inotifywait -r -e modify,create,delete,move,attrib \ --exclude '.*\.mdb$' \ --exclude '.*\.log$' \ --exclude '.*\.check_for_update_done$' \ --exclude '.*/rg$' \ -q "$SOURCE" # Debounce: agar last sync 30s pehle hua ho tabhi sync karo NOW=$(date +%s) DIFF=$((NOW - LAST_SYNC)) if [ "$DIFF" -ge 30 ]; then do_sync LAST_SYNC=$(date +%s) else echo "=== [STEP 3] Change detected but debounce active (${DIFF}s < 30s), waiting... ===" fi done