Files
italiadatacenter/st2idc/restorePG.sh
T
2026-08-26 10:45:35 +02:00

163 lines
5.6 KiB
Bash

#!/bin/bash
set -Eeuo pipefail
# Configuration
TARGET_ENV="${1:-stsharedservices-dev}"
DBNAME="${2:-geco}"
POD_NAME="${3:-stpgclusterdev-1}"
CONTAINER_NAME="${4:-postgres}"
BACKUP_FILE="${5:-.}"
DROP_IF_EXISTS="${6:-true}"
DB_USER="${7:-${PGUSER:-postgres}}"
DB_PASSWORD="${8:-${PGPASSWORD:-}}"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Logging functions
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $*"
}
error() {
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $*" >&2
exit 1
}
warn() {
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARN:${NC} $*"
}
info() {
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO:${NC} $*"
}
log "Inizio restore database PostgreSQL"
log "Namespace target: ${TARGET_ENV}"
log "Pod target: ${POD_NAME}"
log "Database: ${DBNAME}"
log "DB user: ${DB_USER}"
log "File backup: ${BACKUP_FILE}"
# Validate backup file exists
if [ ! -f "${BACKUP_FILE}" ]; then
error "File di backup non trovato: ${BACKUP_FILE}"
fi
FILE_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1)
log "Dimensione file backup: ${FILE_SIZE}"
# Determine if backup is compressed
if [[ "${BACKUP_FILE}" == *.gz ]]; then
IS_COMPRESSED=true
info "Backup compresso (gzip) rilevato"
else
IS_COMPRESSED=false
info "Backup non compresso rilevato"
fi
# Check if namespace exists
if ! kubectl get namespace "${TARGET_ENV}" &>/dev/null; then
error "Namespace '${TARGET_ENV}' non trovato"
fi
# Check if pod exists
if ! kubectl get pod "${POD_NAME}" -n "${TARGET_ENV}" &>/dev/null; then
error "Pod '${POD_NAME}' non trovato nel namespace '${TARGET_ENV}'"
fi
# Check if pod is running
POD_STATUS=$(kubectl get pod "${POD_NAME}" -n "${TARGET_ENV}" -o jsonpath='{.status.phase}')
if [ "${POD_STATUS}" != "Running" ]; then
error "Pod '${POD_NAME}' non è in stato Running (stato attuale: ${POD_STATUS})"
fi
# Check database connectivity
info "Verifica connessione al database..."
if ! kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" pg_isready -U "${DB_USER}" -d "${DBNAME}" &>/dev/null; then
error "Impossibile connettersi a PostgreSQL nel pod '${POD_NAME}'"
fi
log "Connessione al database verificata"
# Drop database if requested
if [ "${DROP_IF_EXISTS}" = "true" ]; then
warn "Elimino il database '${DBNAME}' se esiste..."
kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -c "DROP DATABASE IF EXISTS \"${DBNAME}\" WITH (FORCE);" 2>/dev/null || warn "Database non esiste o elimina non è riuscita"
info "Creo nuovo database '${DBNAME}'..."
kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -c "CREATE DATABASE \"${DBNAME}\";" || error "Impossibile creare il database '${DBNAME}'"
fi
log "Inizio restore del database..."
# Execute restore
if [ "${IS_COMPRESSED}" = "true" ]; then
info "Decompressione e restore in corso..."
gunzip -c "${BACKUP_FILE}" | kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" pg_restore -U "${DB_USER}" -d "${DBNAME}" --no-owner -v 2>&1 | grep -E "(NOTICE|ERROR|completed)" || true
else
info "Restore da file plain SQL in corso..."
cat "${BACKUP_FILE}" | kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -v ON_ERROR_STOP=1 2>&1 | grep -E "(NOTICE|ERROR|INSERT|CREATE)" | tail -20 || true
fi
log "Restore completato"
info "Allineo owner delle tabelle al proprietario del database target..."
TARGET_DB_OWNER=$(kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d postgres -t -A -c "SELECT pg_get_userbyid(datdba) FROM pg_database WHERE datname='${DBNAME}';")
if [ -z "${TARGET_DB_OWNER}" ]; then
error "Impossibile determinare l'owner del database '${DBNAME}'"
fi
kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -v ON_ERROR_STOP=1 -c "DO \$\$ DECLARE r RECORD; BEGIN FOR r IN SELECT n.nspname, c.relname FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('r', 'p') AND n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname NOT LIKE 'pg_toast%' LOOP EXECUTE format('ALTER TABLE %I.%I OWNER TO %I', r.nspname, r.relname, '${TARGET_DB_OWNER}'); END LOOP; END \$\$;" >/dev/null
log "Owner tabelle allineato a '${TARGET_DB_OWNER}'"
# Verify restore success
info "Verifica integrità database..."
TABLE_COUNT=$(kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='public';" 2>/dev/null || echo "0")
if [ "${TABLE_COUNT}" -gt 0 ]; then
log "✅ Restore completato con successo"
log "Database '${DBNAME}' contiene ${TABLE_COUNT} tabelle"
else
warn "⚠️ Database '${DBNAME}' non contiene tabelle pubbliche (potrebbe essere empty)"
fi
# Get database size
DB_SIZE=$(kubectl exec -i "${POD_NAME}" \
-c "${CONTAINER_NAME}" \
-n "${TARGET_ENV}" \
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -t -c "SELECT pg_size_pretty(pg_database_size('${DBNAME}'));" 2>/dev/null || echo "N/A")
log "Dimensione database: ${DB_SIZE}"
log "✅ Restore completato con successo"