Adopt HHF Technology stack structure for Pangolin backup and updates
This commit is contained in:
1 parent
877ff62105
commit
7875ef0bc2
2 files changed
+60
-15
No files matched your search
+34
-12
@@ -90,45 +90,67 @@ async def run_backup_task(
|
|||||||
f'''
|
f'''
|
||||||
eval P_DIR="{p_dir}"
|
eval P_DIR="{p_dir}"
|
||||||
P_DIR="${{P_DIR/#~/$HOME}}"
|
P_DIR="${{P_DIR/#~/$HOME}}"
|
||||||
|
|
||||||
|
# Auto-discovery if configured directory does not exist or is empty
|
||||||
if [ ! -d "$P_DIR" ] || [ -z "$(ls -A "$P_DIR" 2>/dev/null)" ]; then
|
if [ ! -d "$P_DIR" ] || [ -z "$(ls -A "$P_DIR" 2>/dev/null)" ]; then
|
||||||
echo "Notice: Configured path $P_DIR is empty or does not exist."
|
echo "Notice: Configured path $P_DIR is empty or does not exist."
|
||||||
echo "Searching VPS for Pangolin Docker compose stack..."
|
echo "Searching VPS for Pangolin Docker compose stack..."
|
||||||
DETECTED=$(docker inspect --format '{{{{index .Config.Labels "com.docker.compose.project.working_dir"}}}}' $(docker ps -aq --filter "name=pangolin" 2>/dev/null) 2>/dev/null | head -n 1)
|
DETECTED=$(docker inspect --format '{{{{index .Config.Labels "com.docker.compose.project.working_dir"}}}}' $(docker ps -aq --filter "name=pangolin" 2>/dev/null) 2>/dev/null | head -n 1)
|
||||||
if [ -z "$DETECTED" ] || [ ! -d "$DETECTED" ]; then
|
if [ -z "$DETECTED" ] || [ ! -d "$DETECTED" ]; then
|
||||||
for candidate in "$HOME/config" "/root/config" "$HOME/pangolin" "/root/pangolin" "$HOME" "/opt/pangolin" /home/*/pangolin /var/lib/pangolin /srv/pangolin /etc/pangolin; do
|
for candidate in "$HOME/config" "/root/config" "$HOME" "/root" "$HOME/pangolin" "/root/pangolin" "/opt/pangolin"; do
|
||||||
if [ -d "$candidate" ] && [ -n "$(ls -A "$candidate" 2>/dev/null)" ]; then
|
if [ -d "$candidate" ] && [ -n "$(ls -A "$candidate" 2>/dev/null)" ]; then
|
||||||
DETECTED="$candidate"
|
DETECTED="$candidate"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if [ -n "$DETECTED" ] && [ -d "$DETECTED" ] && [ -n "$(ls -A "$DETECTED" 2>/dev/null)" ]; then
|
if [ -n "$DETECTED" ] && [ -d "$DETECTED" ]; then
|
||||||
echo "--> Auto-discovered active Pangolin directory at: $DETECTED"
|
echo "--> Auto-discovered active Pangolin directory at: $DETECTED"
|
||||||
P_DIR="$DETECTED"
|
P_DIR="$DETECTED"
|
||||||
else
|
|
||||||
echo "--> Warning: Could not locate alternate Pangolin directory. Staging from $P_DIR"
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Standard HHF Pangolin stack items
|
||||||
|
BACKUP_ITEMS=("docker-compose.yml" "compose.yaml" "docker-compose.yaml" ".env" "config" "crowdsec" "traefik")
|
||||||
|
|
||||||
echo "--- Staging Pangolin files from $P_DIR ---"
|
echo "--- Staging Pangolin files from $P_DIR ---"
|
||||||
if [ -d "$P_DIR" ]; then
|
if [ -d "$P_DIR" ]; then
|
||||||
rsync -av --exclude="*.db" --exclude="*.db-wal" --exclude="*.db-shm" "$P_DIR/" "{remote_stage}/pangolin/"
|
if [ -f "$P_DIR/docker-compose.yml" ] || [ -d "$P_DIR/config" ]; then
|
||||||
# If compose or env file lives in parent folder (e.g. ~ when config is ~/config), include them too
|
echo "Detected Pangolin stack root at $P_DIR"
|
||||||
|
for item in "${{BACKUP_ITEMS[@]}}"; do
|
||||||
|
if [ -e "$P_DIR/$item" ]; then
|
||||||
|
echo "Staging $item..."
|
||||||
|
mkdir -p "{remote_stage}/pangolin/$(dirname "$item")"
|
||||||
|
cp -a "$P_DIR/$item" "{remote_stage}/pangolin/$item" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "Staging contents of $P_DIR into {remote_stage}/pangolin/config/..."
|
||||||
|
mkdir -p "{remote_stage}/pangolin/config"
|
||||||
|
rsync -av --exclude="*.db" --exclude="*.db-wal" --exclude="*.db-shm" "$P_DIR/" "{remote_stage}/pangolin/config/"
|
||||||
|
|
||||||
|
# Check parent folder for companion compose and env files
|
||||||
PARENT_DIR="$(dirname "$P_DIR")"
|
PARENT_DIR="$(dirname "$P_DIR")"
|
||||||
for extra in docker-compose.yml compose.yaml docker-compose.yaml .env; do
|
for extra in docker-compose.yml compose.yaml docker-compose.yaml .env; do
|
||||||
if [ -f "$PARENT_DIR/$extra" ] && [ ! -f "{remote_stage}/pangolin/$extra" ]; then
|
if [ -f "$PARENT_DIR/$extra" ]; then
|
||||||
echo "--- Staging companion $extra from $PARENT_DIR ---"
|
echo "--- Staging companion $extra from $PARENT_DIR ---"
|
||||||
cp "$PARENT_DIR/$extra" "{remote_stage}/pangolin/" 2>/dev/null || true
|
cp "$PARENT_DIR/$extra" "{remote_stage}/pangolin/" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo "--- Performing zero-lock hot-backup of SQLite databases on VPS ---"
|
echo "--- Performing zero-lock hot-backup of SQLite databases on VPS ---"
|
||||||
for db in $(find "$P_DIR" -name "*.db" -o -name "*.sqlite" 2>/dev/null); do
|
# Search in P_DIR, P_DIR/config, and $(dirname P_DIR)
|
||||||
rel=$(realpath --relative-to="$P_DIR" "$db")
|
for search_path in "$P_DIR" "$P_DIR/config" "$(dirname "$P_DIR")"; do
|
||||||
mkdir -p "{remote_stage}/pangolin/$(dirname "$rel")"
|
if [ -d "$search_path" ]; then
|
||||||
echo "Hot-backing up $rel..."
|
for db in $(find "$search_path" -maxdepth 2 -name "*.db" -o -name "*.sqlite" 2>/dev/null); do
|
||||||
sqlite3 "$db" ".backup '{remote_stage}/pangolin/$rel'" 2>/dev/null || cp -v "$db" "{remote_stage}/pangolin/$rel"
|
dbname=$(basename "$db")
|
||||||
|
echo "Hot-backing up database: $dbname (source: $db)..."
|
||||||
|
mkdir -p "{remote_stage}/pangolin/config"
|
||||||
|
sqlite3 "$db" ".backup '{remote_stage}/pangolin/config/$dbname'" 2>/dev/null || cp -v "$db" "{remote_stage}/pangolin/config/$dbname"
|
||||||
|
done
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Backup any named Docker volumes attached to pangolin containers
|
# Backup any named Docker volumes attached to pangolin containers
|
||||||
|
|||||||
+26
-3
@@ -157,16 +157,39 @@ async def trigger_pangolin_update() -> Dict[str, Any]:
|
|||||||
|
|
||||||
# Remote update script executed on the VPS
|
# Remote update script executed on the VPS
|
||||||
remote_script = f"""
|
remote_script = f"""
|
||||||
|
eval P_DIR="{p_dir}"
|
||||||
|
P_DIR="${{P_DIR/#~/$HOME}}"
|
||||||
|
|
||||||
|
# Locate compose directory
|
||||||
|
if [ -f "$P_DIR/docker-compose.yml" ] || [ -f "$P_DIR/compose.yaml" ]; then
|
||||||
|
COMPOSE_DIR="$P_DIR"
|
||||||
|
elif [ -f "$(dirname "$P_DIR")/docker-compose.yml" ] || [ -f "$(dirname "$P_DIR")/compose.yaml" ]; then
|
||||||
|
COMPOSE_DIR="$(dirname "$P_DIR")"
|
||||||
|
else
|
||||||
|
COMPOSE_DIR="$P_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "=== STEP 1: Connecting to Pangolin VPS ({vps_host}) ==="
|
echo "=== STEP 1: Connecting to Pangolin VPS ({vps_host}) ==="
|
||||||
cd "{p_dir}" || exit 1
|
echo "Operating Directory: $COMPOSE_DIR"
|
||||||
|
cd "$COMPOSE_DIR" || exit 1
|
||||||
|
|
||||||
|
# Detect docker compose version
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
DC="docker compose"
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
DC="docker-compose"
|
||||||
|
else
|
||||||
|
echo "ERROR: Neither 'docker compose' nor 'docker-compose' found on VPS."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== STEP 2: Pulling latest images on VPS ==="
|
echo "=== STEP 2: Pulling latest images on VPS ==="
|
||||||
docker compose pull
|
$DC pull
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== STEP 3: Applying stack updates & recreating containers ==="
|
echo "=== STEP 3: Applying stack updates & recreating containers ==="
|
||||||
docker compose up -d --remove-orphans
|
$DC up -d --remove-orphans
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== STEP 4: Verifying running container status ==="
|
echo "=== STEP 4: Verifying running container status ==="
|
||||||
|
|||||||
Reference in new issue
Block a user