| |
| FROM lbjlaq/antigravity-manager:latest |
|
|
| USER root |
| RUN apt-get update && apt-get install -y --no-install-recommends curl jq && rm -rf /var/lib/apt/lists/* |
|
|
| ENV DATA_DIR=/root/.antigravity_tools |
| ENV SYNC_INTERVAL=150 |
| EXPOSE 8045 |
|
|
| COPY --chmod=755 <<'SCRIPT' /entrypoint.sh |
| |
| set -e |
|
|
| DATA_DIR="${DATA_DIR:-/root/.antigravity_tools}" |
| SYNC_INTERVAL="${SYNC_INTERVAL:-30}" |
| LAST_SYNC="/tmp/.last_sync" |
| SUPABASE_PREFIX="antigravity_tools" |
|
|
| |
| supabase_list() { |
| local prefix="$1" response files folders |
| response=$(curl -s -X POST \ |
| "${SUPABASE_URL}/storage/v1/object/list/${SUPABASE_BUCKET}" \ |
| -H "Authorization: Bearer ${SUPABASE_KEY}" \ |
| -H "Content-Type: application/json" \ |
| -d "{\"prefix\":\"${prefix}\",\"limit\":1000}" 2>/dev/null) |
| files=$(echo "$response" | jq -r '.[]? | select(.id != null) | .name' 2>/dev/null) |
| folders=$(echo "$response" | jq -r '.[]? | select(.id == null) | .name' 2>/dev/null) |
| for f in $files; do [ -n "$f" ] && echo "${prefix}${f}"; done |
| for d in $folders; do [ -n "$d" ] && supabase_list "${prefix}${d}/"; done |
| } |
|
|
| supabase_download() { |
| local remote_path="$1" local_path="$2" |
| mkdir -p "$(dirname "$local_path")" |
| curl -s -o "$local_path" \ |
| "${SUPABASE_URL}/storage/v1/object/${SUPABASE_BUCKET}/${remote_path}" \ |
| -H "Authorization: Bearer ${SUPABASE_KEY}" |
| } |
|
|
| supabase_upload() { |
| local local_path="$1" remote_path="$2" |
| curl -s -X POST \ |
| "${SUPABASE_URL}/storage/v1/object/${SUPABASE_BUCKET}/${remote_path}" \ |
| -H "Authorization: Bearer ${SUPABASE_KEY}" \ |
| -H "Content-Type: application/octet-stream" \ |
| -H "x-upsert: true" \ |
| --data-binary "@${local_path}" > /dev/null 2>&1 |
| } |
|
|
| supabase_has_data() { |
| local r |
| r=$(curl -s -X POST \ |
| "${SUPABASE_URL}/storage/v1/object/list/${SUPABASE_BUCKET}" \ |
| -H "Authorization: Bearer ${SUPABASE_KEY}" \ |
| -H "Content-Type: application/json" \ |
| -d "{\"prefix\":\"${SUPABASE_PREFIX}/\",\"limit\":1}" 2>/dev/null) |
| [ "$(echo "$r" | jq 'length' 2>/dev/null)" != "0" ] |
| } |
|
|
| |
| pull_from_supabase() { |
| echo "[Sync] Pulling from Supabase..." |
| local count=0 |
| supabase_list "${SUPABASE_PREFIX}/" | while read -r remote_path; do |
| local rel="${remote_path#${SUPABASE_PREFIX}/}" |
| local local_path="$DATA_DIR/$rel" |
| supabase_download "$remote_path" "$local_path" |
| echo "[Sync] <- $rel" |
| count=$((count + 1)) |
| done |
| touch "$LAST_SYNC" |
| echo "[Sync] Pull complete!" |
| } |
|
|
| |
| push_all() { |
| echo "[Sync] Pushing entire directory..." |
| find "$DATA_DIR" -type f | while read -r filepath; do |
| local rel="${filepath#$DATA_DIR/}" |
| supabase_upload "$filepath" "${SUPABASE_PREFIX}/${rel}" |
| echo "[Sync] -> $rel" |
| done |
| touch "$LAST_SYNC" |
| echo "[Sync] Push complete at $(date '+%H:%M:%S')" |
| } |
|
|
| |
| push_changed() { |
| find "$DATA_DIR" -type f -newer "$LAST_SYNC" 2>/dev/null | while read -r filepath; do |
| local rel="${filepath#$DATA_DIR/}" |
| supabase_upload "$filepath" "${SUPABASE_PREFIX}/${rel}" |
| echo "[Sync] -> $rel" |
| done |
| touch "$LAST_SYNC" |
| } |
|
|
| |
| SYNC="" |
| [ -n "$SUPABASE_URL" ] && [ -n "$SUPABASE_KEY" ] && [ -n "$SUPABASE_BUCKET" ] && SYNC="1" |
|
|
| |
| if [ -n "$SYNC" ]; then |
| echo "[Sync] Checking Supabase for existing data..." |
| if supabase_has_data; then |
| pull_from_supabase |
| else |
| echo "[Sync] Empty bucket β first run." |
| fi |
| fi |
|
|
| |
| /app/antigravity-tools --headless & |
| APP_PID=$! |
|
|
| |
| if [ -n "$SYNC" ] && [ ! -f "$LAST_SYNC" ]; then |
| echo "[Sync] Waiting for app to create data..." |
| while [ ! -d "$DATA_DIR" ]; do sleep 2; done |
| sleep 5 |
| push_all |
| fi |
|
|
| |
| if [ -n "$SYNC" ]; then |
| ( |
| while kill -0 $APP_PID 2>/dev/null; do |
| sleep "$SYNC_INTERVAL" |
| push_changed || true |
| done |
| ) & |
| SYNC_PID=$! |
| fi |
|
|
| |
| cleanup() { |
| echo "[Sync] Shutting down β final push..." |
| [ -n "$SYNC" ] && [ -d "$DATA_DIR" ] && push_all |
| kill $APP_PID 2>/dev/null |
| [ -n "$SYNC_PID" ] && kill $SYNC_PID 2>/dev/null |
| wait $APP_PID 2>/dev/null |
| exit 0 |
| } |
| trap cleanup SIGTERM SIGINT |
|
|
| wait $APP_PID |
| SCRIPT |
|
|
| ENTRYPOINT ["/entrypoint.sh"] |