e736dd0f37
Made-with: Cursor
108 lines
2.9 KiB
Bash
Executable File
108 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Backup helper for OpenClaude local stack.
|
|
#
|
|
# Creates timestamped backup with:
|
|
# - OpenClaude/Claude config files (if present)
|
|
# - env profiles (without rewriting)
|
|
# - Ollama model list and metadata
|
|
# - optional Qdrant collection snapshot (if API is reachable)
|
|
#
|
|
# Usage:
|
|
# ./backup.sh
|
|
# ./backup.sh --output-dir /path/to/backups
|
|
# ./backup.sh --collection mydocs
|
|
|
|
OUTPUT_DIR="${OUTPUT_DIR:-$HOME/openclaude-backups}"
|
|
COLLECTION="${QDRANT_COLLECTION:-docs}"
|
|
QDRANT_URL="${QDRANT_URL:-http://127.0.0.1:6333}"
|
|
STAMP="$(date +%Y%m%d_%H%M%S)"
|
|
TARGET=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--output-dir)
|
|
OUTPUT_DIR="$2"
|
|
shift 2
|
|
;;
|
|
--collection)
|
|
COLLECTION="$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "Unknown argument: $1"
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
mkdir -p "$OUTPUT_DIR"
|
|
TARGET="${OUTPUT_DIR}/backup_${STAMP}"
|
|
mkdir -p "$TARGET"
|
|
|
|
echo "==> Backup target: $TARGET"
|
|
|
|
copy_if_exists() {
|
|
local src="$1"
|
|
local dst="$2"
|
|
if [[ -e "$src" ]]; then
|
|
mkdir -p "$(dirname "$dst")"
|
|
cp -R "$src" "$dst"
|
|
echo " copied: $src"
|
|
fi
|
|
}
|
|
|
|
echo "==> Backing up configs"
|
|
copy_if_exists "$HOME/.claude/settings.json" "$TARGET/config/claude/settings.json"
|
|
copy_if_exists "$HOME/.claude.json" "$TARGET/config/claude/claude.json"
|
|
copy_if_exists "$HOME/.config/openclaude/profiles" "$TARGET/config/openclaude/profiles"
|
|
|
|
echo "==> Backing up model inventory"
|
|
if command -v ollama >/dev/null 2>&1; then
|
|
ollama list > "$TARGET/ollama_models.txt" || true
|
|
ollama ps > "$TARGET/ollama_running.txt" || true
|
|
echo " saved: ollama model inventory"
|
|
else
|
|
echo " skip: ollama not installed"
|
|
fi
|
|
|
|
echo "==> Exporting Qdrant collection (if available)"
|
|
if curl -fsS "${QDRANT_URL}/collections/${COLLECTION}" >/dev/null 2>&1; then
|
|
mkdir -p "$TARGET/qdrant"
|
|
curl -fsS "${QDRANT_URL}/collections/${COLLECTION}" > "$TARGET/qdrant/${COLLECTION}_meta.json"
|
|
|
|
# Try to export up to 10000 points via scroll API.
|
|
# This is a practical backup for small/medium collections.
|
|
curl -fsS -X POST "${QDRANT_URL}/collections/${COLLECTION}/points/scroll" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"limit":10000,"with_payload":true,"with_vector":false}' \
|
|
> "$TARGET/qdrant/${COLLECTION}_points.json" || true
|
|
|
|
echo " saved: qdrant metadata and points snapshot"
|
|
else
|
|
echo " skip: qdrant collection not reachable (${COLLECTION})"
|
|
fi
|
|
|
|
cat > "$TARGET/RESTORE_NOTES.txt" <<EOF
|
|
Restore notes:
|
|
|
|
1) Restore configs:
|
|
cp -R "$TARGET/config/"* "$HOME/" # adjust manually per file
|
|
|
|
2) Restore model list:
|
|
open "$TARGET/ollama_models.txt" and pull needed models:
|
|
ollama pull <model:tag>
|
|
|
|
3) Restore Qdrant collection data:
|
|
- Ensure Qdrant is running.
|
|
- Recreate collection if needed.
|
|
- Reindex from source docs (recommended) OR replay points from:
|
|
$TARGET/qdrant/${COLLECTION}_points.json
|
|
|
|
Note: reindex from original documents is the safest restore method.
|
|
EOF
|
|
|
|
echo
|
|
echo "Backup completed: $TARGET"
|