fix : t 021 a 033 fait
This commit is contained in:
@@ -113,11 +113,14 @@ mkdir -p "$LOCAL_BACKUP"
|
|||||||
#######################################
|
#######################################
|
||||||
# Notification Discord
|
# Notification Discord
|
||||||
#######################################
|
#######################################
|
||||||
discord_ping() {
|
send_discord() {
|
||||||
local success="$1"
|
local success="$1"
|
||||||
local details="${2:-}"
|
local details="${2:-}"
|
||||||
|
local payload=""
|
||||||
|
|
||||||
[[ -z "$DISCORD_WEBHOOK_URL" ]] && return 0
|
[[ -z "$DISCORD_WEBHOOK_URL" ]] && return 0
|
||||||
|
require_cmd jq || return 0
|
||||||
|
require_cmd curl || return 0
|
||||||
|
|
||||||
local icon status_line
|
local icon status_line
|
||||||
if [[ "$success" == "true" ]]; then
|
if [[ "$success" == "true" ]]; then
|
||||||
@@ -136,7 +139,6 @@ discord_ping() {
|
|||||||
msg+="Data transfer: ${status_line}\n"
|
msg+="Data transfer: ${status_line}\n"
|
||||||
[[ -n "$details" ]] && msg+="Détails: ${details}"
|
[[ -n "$details" ]] && msg+="Détails: ${details}"
|
||||||
|
|
||||||
local payload
|
|
||||||
payload="$(jq -n --arg content "$msg" '{content: $content}')"
|
payload="$(jq -n --arg content "$msg" '{content: $content}')"
|
||||||
curl -fsS -H "Content-Type: application/json" -d "$payload" "$DISCORD_WEBHOOK_URL" >/dev/null || true
|
curl -fsS -H "Content-Type: application/json" -d "$payload" "$DISCORD_WEBHOOK_URL" >/dev/null || true
|
||||||
}
|
}
|
||||||
@@ -147,7 +149,7 @@ discord_ping() {
|
|||||||
fail() {
|
fail() {
|
||||||
local detail="$1"
|
local detail="$1"
|
||||||
log "ERROR: $detail"
|
log "ERROR: $detail"
|
||||||
discord_ping "false" "$detail"
|
send_discord "false" "$detail"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,6 +167,7 @@ if ! mkdir "$LOCK_DIR" 2>/dev/null; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
|
rm -f "${LOCAL_BACKUP_FILE:-}"
|
||||||
rm -rf -- "$LOCK_DIR"
|
rm -rf -- "$LOCK_DIR"
|
||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
@@ -227,5 +230,5 @@ rm -f "$LOCAL_BACKUP_FILE" || fail "Impossible de supprimer le backup local $LOC
|
|||||||
# Fin
|
# Fin
|
||||||
#######################################
|
#######################################
|
||||||
log "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR"
|
log "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR"
|
||||||
discord_ping "true" "Backup envoyé avec succès vers $REMOTE_HOST"
|
send_discord "true" "Backup envoyé avec succès vers $REMOTE_HOST"
|
||||||
echo "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR"
|
echo "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR"
|
||||||
|
|||||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -5,6 +5,20 @@ et applique le versionnement semantique.
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Harmonisation des fonctions d'envoi Discord dans les scripts de sauvegarde, de supervision et de reconstruction.
|
||||||
|
- Ajout d'un fichier de log dedie a l'orchestrateur `RebuildBdd/run-rebuild-bdd.sh`.
|
||||||
|
- Renforcement de la journalisation et de la gestion des erreurs dans `RecetteScripts/backup-bdd-recette.sh`.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Nettoyage du backup local temporaire dans `BackupVaultWarden/backup-vaultwarden.sh` en sortie de script.
|
||||||
|
- Gestion plus robuste des dependances shell et des verifications de disponibilite PostgreSQL dans les scripts `RebuildBdd`.
|
||||||
|
- Acceptation explicite du flag `--non-interactive` dans `RebuildBdd/Checkup/check-target-readiness.sh` pour compatibilite de workflow.
|
||||||
|
- Validation des noms de base et refus des cles SSH symboliques dans les scripts de reconstruction.
|
||||||
|
- Suppression des notifications Discord fragiles quand `jq` ou `curl` sont absents, avec envoi silencieux en secours.
|
||||||
|
- Detection et nettoyage des verrous perimes dans `RecetteScripts/backup-bdd-recette.sh`.
|
||||||
|
- Filtrage des privileges `SUPERUSER` lors de la restauration des roles dans `RecetteScripts/rebuild-bdd-recette.sh`.
|
||||||
|
|
||||||
## [1.0.0] - 2026-03-18
|
## [1.0.0] - 2026-03-18
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -52,6 +52,20 @@ if [[ -n "${DISCORD_WEBHOOK_URL:-}" ]]; then
|
|||||||
require_cmd curl
|
require_cmd curl
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
send_discord() {
|
||||||
|
local message="$1"
|
||||||
|
local payload=""
|
||||||
|
|
||||||
|
[[ -n "${DISCORD_WEBHOOK_URL:-}" ]] || return 0
|
||||||
|
|
||||||
|
payload="$(jq -n --arg content "$message" '{content: $content}')" || return 0
|
||||||
|
|
||||||
|
curl -fsS \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$payload" \
|
||||||
|
"$DISCORD_WEBHOOK_URL" >/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# RÉCUPÉRATION DES INFORMATIONS DISQUE
|
# RÉCUPÉRATION DES INFORMATIONS DISQUE
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -77,15 +91,7 @@ if [ "$usage" -ge "$limit" ]; then
|
|||||||
|
|
||||||
msgLimit="${DISCORD_PING}\n**CHECK STOCKAGE :red_circle:**\nLimite autorisée : ${limit}%\nUtilisation actuelle : ${usage}%\nEspace restant : ${free}%\nUtilisé / total : ${used_gb} GB / ${total_gb} GB\nDisponible : ${avail_gb} GB\nHeure : $(date)"
|
msgLimit="${DISCORD_PING}\n**CHECK STOCKAGE :red_circle:**\nLimite autorisée : ${limit}%\nUtilisation actuelle : ${usage}%\nEspace restant : ${free}%\nUtilisé / total : ${used_gb} GB / ${total_gb} GB\nDisponible : ${avail_gb} GB\nHeure : $(date)"
|
||||||
|
|
||||||
if [[ -n "${DISCORD_WEBHOOK_URL:-}" ]]; then
|
send_discord "$msgLimit"
|
||||||
payload="$(jq -n --arg content "$msgLimit" '{content: $content}')"
|
|
||||||
|
|
||||||
curl -fsS \
|
|
||||||
-H "Accept: application/json" \
|
|
||||||
-H "Content-Type: application/json; charset=utf-8" \
|
|
||||||
-d "$payload" \
|
|
||||||
"$DISCORD_WEBHOOK_URL" >/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -41,19 +41,19 @@ fail() {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
require_cmd() {
|
has_cmd() {
|
||||||
command -v "$1" >/dev/null 2>&1
|
command -v "$1" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
postgres_server_ready() {
|
postgres_server_ready() {
|
||||||
require_cmd postgres || return 1
|
has_cmd postgres || return 1
|
||||||
require_cmd pg_ctlcluster || return 1
|
has_cmd pg_ctlcluster || return 1
|
||||||
require_cmd pg_lsclusters || return 1
|
has_cmd pg_lsclusters || return 1
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_postgres_cluster() {
|
ensure_postgres_cluster() {
|
||||||
if ! require_cmd pg_lsclusters || ! require_cmd pg_createcluster; then
|
if ! has_cmd pg_lsclusters || ! has_cmd pg_createcluster; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ ensure_postgres_cluster() {
|
|||||||
version="$(find /etc/postgresql -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | LC_ALL=C sort -V | tail -n 1)"
|
version="$(find /etc/postgresql -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | LC_ALL=C sort -V | tail -n 1)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "$version" ]] && require_cmd psql; then
|
if [[ -z "$version" ]] && has_cmd psql; then
|
||||||
version="$(psql --version 2>/dev/null | awk '{print $3}' | cut -d. -f1)"
|
version="$(psql --version 2>/dev/null | awk '{print $3}' | cut -d. -f1)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -82,15 +82,15 @@ collect_postgres_diagnostics() {
|
|||||||
|
|
||||||
if "$SUDO_BIN" systemctl status "$POSTGRES_SERVICE_NAME" --no-pager >/dev/null 2>&1; then
|
if "$SUDO_BIN" systemctl status "$POSTGRES_SERVICE_NAME" --no-pager >/dev/null 2>&1; then
|
||||||
diagnostics+="systemctl status ${POSTGRES_SERVICE_NAME}: OK; "
|
diagnostics+="systemctl status ${POSTGRES_SERVICE_NAME}: OK; "
|
||||||
elif require_cmd systemctl; then
|
elif has_cmd systemctl; then
|
||||||
diagnostics+="systemctl status ${POSTGRES_SERVICE_NAME}: $( "$SUDO_BIN" systemctl status "$POSTGRES_SERVICE_NAME" --no-pager 2>/dev/null | tail -n 5 | tr '\n' ' ' ); "
|
diagnostics+="systemctl status ${POSTGRES_SERVICE_NAME}: $( "$SUDO_BIN" systemctl status "$POSTGRES_SERVICE_NAME" --no-pager 2>/dev/null | tail -n 5 | tr '\n' ' ' ); "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if require_cmd pg_lsclusters; then
|
if has_cmd pg_lsclusters; then
|
||||||
diagnostics+="pg_lsclusters: $(pg_lsclusters --no-header 2>/dev/null | tr '\n' ' '); "
|
diagnostics+="pg_lsclusters: $(pg_lsclusters --no-header 2>/dev/null | tr '\n' ' '); "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if require_cmd journalctl; then
|
if has_cmd journalctl; then
|
||||||
diagnostics+="journalctl: $( "$SUDO_BIN" journalctl -u "$POSTGRES_SERVICE_NAME" -n 10 --no-pager 2>/dev/null | tr '\n' ' ' ); "
|
diagnostics+="journalctl: $( "$SUDO_BIN" journalctl -u "$POSTGRES_SERVICE_NAME" -n 10 --no-pager 2>/dev/null | tr '\n' ' ' ); "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -102,11 +102,11 @@ start_postgres_service() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if require_cmd service && "$SUDO_BIN" service "$POSTGRES_SERVICE_NAME" start >/dev/null 2>&1; then
|
if has_cmd service && "$SUDO_BIN" service "$POSTGRES_SERVICE_NAME" start >/dev/null 2>&1; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if require_cmd pg_lsclusters && require_cmd pg_ctlcluster; then
|
if has_cmd pg_lsclusters && has_cmd pg_ctlcluster; then
|
||||||
local version cluster
|
local version cluster
|
||||||
while read -r version cluster _; do
|
while read -r version cluster _; do
|
||||||
[[ -n "$version" && -n "$cluster" ]] || continue
|
[[ -n "$version" && -n "$cluster" ]] || continue
|
||||||
@@ -143,7 +143,7 @@ read -r -a POSTGRES_PACKAGES <<< "$POSTGRES_PACKAGE_LIST"
|
|||||||
|
|
||||||
export PGPASSWORD
|
export PGPASSWORD
|
||||||
|
|
||||||
if ! require_cmd "$SUDO_BIN"; then
|
if ! has_cmd "$SUDO_BIN"; then
|
||||||
fail "sudo absent sur la cible"
|
fail "sudo absent sur la cible"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ fi
|
|||||||
|
|
||||||
POSTGRES_INSTALLED="no"
|
POSTGRES_INSTALLED="no"
|
||||||
|
|
||||||
if ! require_cmd psql || ! require_cmd pg_restore || ! require_cmd createdb || ! require_cmd dropdb || ! postgres_server_ready; then
|
if ! has_cmd psql || ! has_cmd pg_restore || ! has_cmd createdb || ! has_cmd dropdb || ! postgres_server_ready; then
|
||||||
[[ "${AUTO_INSTALL_POSTGRES,,}" == "yes" ]] || fail "PostgreSQL absent et AUTO_INSTALL_POSTGRES=no"
|
[[ "${AUTO_INSTALL_POSTGRES,,}" == "yes" ]] || fail "PostgreSQL absent et AUTO_INSTALL_POSTGRES=no"
|
||||||
|
|
||||||
log "PostgreSQL absent : installation en cours..."
|
log "PostgreSQL absent : installation en cours..."
|
||||||
@@ -181,15 +181,17 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
log "Vérification de la disponibilité de PostgreSQL..."
|
log "Vérification de la disponibilité de PostgreSQL..."
|
||||||
|
PG_READY=false
|
||||||
for _ in {1..20}; do
|
for _ in {1..20}; do
|
||||||
if "$SUDO_BIN" -u postgres psql -d postgres -c "SELECT 1;" >/dev/null 2>&1; then
|
if "$SUDO_BIN" -u postgres psql -d postgres -c "SELECT 1;" >/dev/null 2>&1; then
|
||||||
|
PG_READY=true
|
||||||
log "PostgreSQL répond correctement."
|
log "PostgreSQL répond correctement."
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
if ! "$SUDO_BIN" -u postgres psql -d postgres -c "SELECT 1;" >/dev/null 2>&1; then
|
if [[ "$PG_READY" != true ]]; then
|
||||||
fail "PostgreSQL ne répond pas correctement"
|
fail "PostgreSQL ne répond pas correctement"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ while [[ $# -gt 0 ]]; do
|
|||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
--non-interactive)
|
--non-interactive)
|
||||||
|
# Flag accepté pour compatibilité avec les autres scripts du workflow.
|
||||||
NON_INTERACTIVE="yes"
|
NON_INTERACTIVE="yes"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -97,6 +97,10 @@ fail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
require_cmd() {
|
require_cmd() {
|
||||||
|
command -v "$1" >/dev/null 2>&1 || fail "commande requise absente : $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
has_cmd() {
|
||||||
command -v "$1" >/dev/null 2>&1
|
command -v "$1" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +141,13 @@ sql_escape_literal() {
|
|||||||
printf "%s" "$s"
|
printf "%s" "$s"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate_db_name() {
|
||||||
|
local db_name="${1:-}"
|
||||||
|
|
||||||
|
[[ -n "$db_name" ]] || return 1
|
||||||
|
[[ "$db_name" =~ ^[a-zA-Z0-9_]+$ ]] || return 1
|
||||||
|
}
|
||||||
|
|
||||||
build_excluded_roles_regex() {
|
build_excluded_roles_regex() {
|
||||||
local roles_string="${1:-}"
|
local roles_string="${1:-}"
|
||||||
local role
|
local role
|
||||||
@@ -168,6 +179,22 @@ build_excluded_roles_regex() {
|
|||||||
printf '%s' "$joined"
|
printf '%s' "$joined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
send_discord() {
|
||||||
|
local message="$1"
|
||||||
|
local payload=""
|
||||||
|
|
||||||
|
[[ -n "$DISCORD_WEBHOOK_URL" ]] || return 0
|
||||||
|
has_cmd jq || return 0
|
||||||
|
has_cmd curl || return 0
|
||||||
|
|
||||||
|
payload="$(jq -n --arg content "$message" '{content: $content}')" || return 0
|
||||||
|
|
||||||
|
curl -fsS "$DISCORD_WEBHOOK_URL" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$payload" \
|
||||||
|
>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
rm -f \
|
rm -f \
|
||||||
"${LOCAL_DB_DUMP_FILE:-}" \
|
"${LOCAL_DB_DUMP_FILE:-}" \
|
||||||
@@ -252,7 +279,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
for cmd in ssh scp psql pg_restore createdb dropdb python3 grep sed find basename curl; do
|
for cmd in ssh scp psql pg_restore createdb dropdb python3 grep sed find basename curl; do
|
||||||
require_cmd "$cmd" || fail "commande requise absente : $cmd"
|
require_cmd "$cmd"
|
||||||
done
|
done
|
||||||
|
|
||||||
CHECK_SCRIPT="${SCRIPT_DIR}/Checkup/check-postgresql.sh"
|
CHECK_SCRIPT="${SCRIPT_DIR}/Checkup/check-postgresql.sh"
|
||||||
@@ -264,6 +291,7 @@ fi
|
|||||||
|
|
||||||
[[ -f "$SSH_KEY" ]] || fail "clé SSH source backup introuvable : $SSH_KEY"
|
[[ -f "$SSH_KEY" ]] || fail "clé SSH source backup introuvable : $SSH_KEY"
|
||||||
[[ -r "$SSH_KEY" ]] || fail "clé SSH source backup non lisible : $SSH_KEY"
|
[[ -r "$SSH_KEY" ]] || fail "clé SSH source backup non lisible : $SSH_KEY"
|
||||||
|
[[ ! -L "$SSH_KEY" ]] || fail "clé SSH source backup ne doit pas être un lien symbolique : $SSH_KEY"
|
||||||
|
|
||||||
export PGPASSWORD
|
export PGPASSWORD
|
||||||
|
|
||||||
@@ -319,7 +347,7 @@ for candidate in "${DBS_ARRAY[@]}"; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
[[ -n "$DB" ]] || fail "base refusée : non présente dans DBS"
|
[[ -n "$DB" ]] || fail "base refusée : non présente dans DBS"
|
||||||
[[ "$DB" =~ ^[a-zA-Z0-9_]+$ ]] || fail "nom de base invalide"
|
validate_db_name "$DB" || fail "nom de base invalide"
|
||||||
|
|
||||||
log "Environnement : $ENV_NAME"
|
log "Environnement : $ENV_NAME"
|
||||||
log "Base cible : $DB"
|
log "Base cible : $DB"
|
||||||
@@ -479,27 +507,13 @@ pg_restore \
|
|||||||
"$LOCAL_DB_DUMP_FILE" \
|
"$LOCAL_DB_DUMP_FILE" \
|
||||||
>>"$LOG_FILE" 2>&1 || fail "échec restauration base ${DB}"
|
>>"$LOG_FILE" 2>&1 || fail "échec restauration base ${DB}"
|
||||||
|
|
||||||
send_discord_message() {
|
|
||||||
local message="$1"
|
|
||||||
local payload=""
|
|
||||||
|
|
||||||
[[ -n "$DISCORD_WEBHOOK_URL" ]] || return 0
|
|
||||||
|
|
||||||
payload="$(python3 -c 'import json,sys; print(json.dumps({"content": sys.argv[1]}))' "$message")" || return 0
|
|
||||||
|
|
||||||
curl -sS -X POST "$DISCORD_WEBHOOK_URL" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$payload" \
|
|
||||||
>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
SUCCESS_MESSAGE="✅ REBUILD BDD ${ENV_NAME}
|
SUCCESS_MESSAGE="✅ REBUILD BDD ${ENV_NAME}
|
||||||
Base restaurée : ${DB}
|
Base restaurée : ${DB}
|
||||||
Hôte PostgreSQL : ${PGHOST}:${PGPORT}
|
Hôte PostgreSQL : ${PGHOST}:${PGPORT}
|
||||||
Dump utilisé : $(basename "$LAST_REMOTE_DB_DUMP")
|
Dump utilisé : $(basename "$LAST_REMOTE_DB_DUMP")
|
||||||
Log : ${LOG_FILE}"
|
Log : ${LOG_FILE}"
|
||||||
|
|
||||||
send_discord_message "$SUCCESS_MESSAGE"
|
send_discord "$SUCCESS_MESSAGE"
|
||||||
|
|
||||||
log "Restauration terminée avec succès pour ${DB}"
|
log "Restauration terminée avec succès pour ${DB}"
|
||||||
print_json_and_exit "success" "restauration terminée avec succès" 0
|
print_json_and_exit "success" "restauration terminée avec succès" 0
|
||||||
|
|||||||
@@ -124,6 +124,10 @@ REQUESTED_DB="${CLI_DB:-${REQUESTED_DB:-}}"
|
|||||||
ALLOW_OVERWRITE_RAW="${CLI_OVERWRITE:-${ALLOW_OVERWRITE:-no}}"
|
ALLOW_OVERWRITE_RAW="${CLI_OVERWRITE:-${ALLOW_OVERWRITE:-no}}"
|
||||||
RESTORE_ROLES_RAW="${CLI_RESTORE_ROLES:-${RESTORE_ROLES:-yes}}"
|
RESTORE_ROLES_RAW="${CLI_RESTORE_ROLES:-${RESTORE_ROLES:-yes}}"
|
||||||
REQUEST_ID="${CLI_REQUEST_ID:-${REQUEST_ID:-$(date '+%Y%m%d%H%M%S')_$RANDOM}}"
|
REQUEST_ID="${CLI_REQUEST_ID:-${REQUEST_ID:-$(date '+%Y%m%d%H%M%S')_$RANDOM}}"
|
||||||
|
LOG_DIR="${RUN_REBUILD_BDD_LOG_DIR:-${SCRIPT_DIR}/logs}"
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
LOG_FILE="${LOG_DIR}/run_rebuild_bdd_${REQUEST_ID}.log"
|
||||||
|
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||||
|
|
||||||
ALLOW_OVERWRITE="$(to_bool_yes_no "$ALLOW_OVERWRITE_RAW")" || fail "ALLOW_OVERWRITE invalide"
|
ALLOW_OVERWRITE="$(to_bool_yes_no "$ALLOW_OVERWRITE_RAW")" || fail "ALLOW_OVERWRITE invalide"
|
||||||
RESTORE_ROLES="$(to_bool_yes_no "$RESTORE_ROLES_RAW")" || fail "RESTORE_ROLES invalide"
|
RESTORE_ROLES="$(to_bool_yes_no "$RESTORE_ROLES_RAW")" || fail "RESTORE_ROLES invalide"
|
||||||
|
|||||||
@@ -162,17 +162,22 @@ TS="$(date +'%Y-%m-%d_%H-%M-%S')"
|
|||||||
BACKUP_DIR_NAME="backup_${TS}"
|
BACKUP_DIR_NAME="backup_${TS}"
|
||||||
LOG_FILE="${LOG_DIR}/${BACKUP_DIR_NAME}.log"
|
LOG_FILE="${LOG_DIR}/${BACKUP_DIR_NAME}.log"
|
||||||
|
|
||||||
|
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||||
|
|
||||||
TMP_DIR="$(mktemp -d /tmp/pg_dump_XXXXXX)" || {
|
TMP_DIR="$(mktemp -d /tmp/pg_dump_XXXXXX)" || {
|
||||||
echo "ERROR: impossible de créer le dossier temporaire" >&2
|
echo "ERROR: impossible de créer le dossier temporaire" >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
exec > >(tee -a "$LOG_FILE") 2>&1
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||||||
|
|
||||||
log() { echo "---- $(date +'%Y-%m-%d %H:%M:%S') ---- $*"; }
|
fail() {
|
||||||
|
log "ERROR: $*"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
require_cmd() {
|
require_cmd() {
|
||||||
command -v "$1" >/dev/null 2>&1
|
command -v "$1" >/dev/null 2>&1 || fail "commande manquante : $1"
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_remove_dir() {
|
safe_remove_dir() {
|
||||||
@@ -192,10 +197,7 @@ export PGPASSWORD
|
|||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
for cmd in ssh scp curl jq pg_dump pg_dumpall mktemp; do
|
for cmd in ssh scp curl jq pg_dump pg_dumpall mktemp; do
|
||||||
require_cmd "$cmd" || {
|
require_cmd "$cmd"
|
||||||
echo "ERROR: commande manquante : $cmd" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ -f "$SSH_KEY" ]] || {
|
[[ -f "$SSH_KEY" ]] || {
|
||||||
@@ -222,14 +224,14 @@ chmod 600 "$SSH_KEY" || true
|
|||||||
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL:-}"
|
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL:-}"
|
||||||
DISCORD_PING="${DISCORD_PING:-@here}"
|
DISCORD_PING="${DISCORD_PING:-@here}"
|
||||||
|
|
||||||
discord_send() {
|
send_discord() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
|
local payload
|
||||||
[[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0
|
[[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0
|
||||||
|
|
||||||
local payload
|
|
||||||
payload="$(jq -n --arg content "$msg" '{content: $content}')" || {
|
payload="$(jq -n --arg content "$msg" '{content: $content}')" || {
|
||||||
log "ERROR: impossible de construire le payload JSON Discord"
|
log "ERROR: impossible de construire le payload JSON Discord"
|
||||||
return 1
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
curl -fsS \
|
curl -fsS \
|
||||||
@@ -251,7 +253,7 @@ Dumps transfer: ✅
|
|||||||
Users transfer: ✅
|
Users transfer: ✅
|
||||||
EOF
|
EOF
|
||||||
)"
|
)"
|
||||||
discord_send "$msg"
|
send_discord "$msg"
|
||||||
}
|
}
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
@@ -265,7 +267,7 @@ discord_msg_users_ok_simple() {
|
|||||||
Users backup validé
|
Users backup validé
|
||||||
EOF
|
EOF
|
||||||
)"
|
)"
|
||||||
discord_send "$msg"
|
send_discord "$msg"
|
||||||
}
|
}
|
||||||
|
|
||||||
discord_msg_users_error() {
|
discord_msg_users_error() {
|
||||||
@@ -297,7 +299,7 @@ EOF
|
|||||||
)"
|
)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
discord_send "$msg"
|
send_discord "$msg"
|
||||||
}
|
}
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
@@ -312,7 +314,7 @@ discord_msg_db_ok_simple() {
|
|||||||
Backup validé : ${db}
|
Backup validé : ${db}
|
||||||
EOF
|
EOF
|
||||||
)"
|
)"
|
||||||
discord_send "$msg"
|
send_discord "$msg"
|
||||||
}
|
}
|
||||||
|
|
||||||
discord_msg_db_error() {
|
discord_msg_db_error() {
|
||||||
@@ -347,7 +349,7 @@ EOF
|
|||||||
)"
|
)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
discord_send "$msg"
|
send_discord "$msg"
|
||||||
}
|
}
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
@@ -370,11 +372,36 @@ declare -A DB_DETAILS
|
|||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
LOCK_DIR="/tmp/pg_multi_dump_stream.lock.d"
|
LOCK_DIR="/tmp/pg_multi_dump_stream.lock.d"
|
||||||
|
LOCK_PID_FILE="${LOCK_DIR}/pid"
|
||||||
|
|
||||||
if ! mkdir "$LOCK_DIR" 2>/dev/null; then
|
if ! mkdir "$LOCK_DIR" 2>/dev/null; then
|
||||||
log "ERROR: Backup déjà en cours"
|
stale_lock="no"
|
||||||
discord_msg_users_error "" "" "Lock already exists"
|
existing_pid=""
|
||||||
exit 1
|
|
||||||
|
if [[ -f "$LOCK_PID_FILE" ]]; then
|
||||||
|
existing_pid="$(<"$LOCK_PID_FILE")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$existing_pid" =~ ^[0-9]+$ ]] && kill -0 "$existing_pid" 2>/dev/null; then
|
||||||
|
log "ERROR: Backup déjà en cours (PID ${existing_pid})"
|
||||||
|
discord_msg_users_error "" "" "Lock already exists (PID ${existing_pid})"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
stale_lock="yes"
|
||||||
|
log "WARNING: lock périmé détecté, nettoyage en cours"
|
||||||
|
rm -rf -- "$LOCK_DIR"
|
||||||
|
|
||||||
|
mkdir "$LOCK_DIR" 2>/dev/null || fail "impossible de recréer le lock après nettoyage"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $$ > "$LOCK_PID_FILE" || {
|
||||||
|
rm -rf -- "$LOCK_DIR"
|
||||||
|
fail "impossible d'écrire le PID du lock"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "${stale_lock:-no}" == "yes" ]]; then
|
||||||
|
log "Lock périmé nettoyé."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
@@ -406,18 +433,18 @@ fi
|
|||||||
|
|
||||||
ROLES_FILE="${TMP_DIR}/user_${TS}.sql"
|
ROLES_FILE="${TMP_DIR}/user_${TS}.sql"
|
||||||
|
|
||||||
set +e
|
|
||||||
|
|
||||||
log "Export des rôles PostgreSQL"
|
log "Export des rôles PostgreSQL"
|
||||||
|
|
||||||
pg_dumpall \
|
if pg_dumpall \
|
||||||
-h "$PGHOST" \
|
-h "$PGHOST" \
|
||||||
-p "$PGPORT" \
|
-p "$PGPORT" \
|
||||||
-U "$PGUSER" \
|
-U "$PGUSER" \
|
||||||
--globals-only \
|
--globals-only \
|
||||||
> "$ROLES_FILE"
|
> "$ROLES_FILE"; then
|
||||||
|
RET=0
|
||||||
RET=$?
|
else
|
||||||
|
RET=$?
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $RET -ne 0 ]]; then
|
if [[ $RET -ne 0 ]]; then
|
||||||
USERS_OK=
|
USERS_OK=
|
||||||
@@ -428,8 +455,11 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${USERS_EXPORT_OK:-}" ]]; then
|
if [[ -n "${USERS_EXPORT_OK:-}" ]]; then
|
||||||
scp "${SCP_OPTS[@]}" "$ROLES_FILE" "$IA_SSH:${BACKUP_REMOTE_DIR}/user/"
|
if scp "${SCP_OPTS[@]}" "$ROLES_FILE" "$IA_SSH:${BACKUP_REMOTE_DIR}/user/"; then
|
||||||
RET=$?
|
RET=0
|
||||||
|
else
|
||||||
|
RET=$?
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $RET -ne 0 ]]; then
|
if [[ $RET -ne 0 ]]; then
|
||||||
USERS_OK=
|
USERS_OK=
|
||||||
@@ -444,14 +474,10 @@ if [[ -n "${USERS_EXPORT_OK:-}" ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Dump des bases
|
# Dump des bases
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
set +e
|
|
||||||
|
|
||||||
for DB in "${DBS_ARRAY[@]}"; do
|
for DB in "${DBS_ARRAY[@]}"; do
|
||||||
FILE="${TMP_DIR}/${DB}_${TS}.dump"
|
FILE="${TMP_DIR}/${DB}_${TS}.dump"
|
||||||
|
|
||||||
@@ -461,8 +487,11 @@ for DB in "${DBS_ARRAY[@]}"; do
|
|||||||
|
|
||||||
log "Dump $DB"
|
log "Dump $DB"
|
||||||
|
|
||||||
pg_dump -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -Fc -d "$DB" -f "$FILE"
|
if pg_dump -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -Fc -d "$DB" -f "$FILE"; then
|
||||||
RET=$?
|
RET=0
|
||||||
|
else
|
||||||
|
RET=$?
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $RET -ne 0 ]]; then
|
if [[ $RET -ne 0 ]]; then
|
||||||
DUMPS_OK=
|
DUMPS_OK=
|
||||||
@@ -472,8 +501,11 @@ for DB in "${DBS_ARRAY[@]}"; do
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
scp "${SCP_OPTS[@]}" "$FILE" "$IA_SSH:${BACKUP_REMOTE_DIR}/${DB}/"
|
if scp "${SCP_OPTS[@]}" "$FILE" "$IA_SSH:${BACKUP_REMOTE_DIR}/${DB}/"; then
|
||||||
RET=$?
|
RET=0
|
||||||
|
else
|
||||||
|
RET=$?
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $RET -ne 0 ]]; then
|
if [[ $RET -ne 0 ]]; then
|
||||||
DUMPS_OK=
|
DUMPS_OK=
|
||||||
@@ -482,18 +514,17 @@ for DB in "${DBS_ARRAY[@]}"; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Rotation distante
|
# Rotation distante
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
log "Starting remote rotation: delete backups older than ${RETENTION_DAYS} days"
|
log "Starting remote rotation: delete backups older than ${RETENTION_DAYS} days"
|
||||||
|
|
||||||
set +e
|
if ssh "${SSH_OPTS[@]}" "$IA_SSH" "find '${BACKUP_REMOTE_DIR}/user' -type f -name 'user_*.sql' -mtime +${RETENTION_DAYS} -delete"; then
|
||||||
|
RET=0
|
||||||
ssh "${SSH_OPTS[@]}" "$IA_SSH" "find '${BACKUP_REMOTE_DIR}/user' -type f -name 'user_*.sql' -mtime +${RETENTION_DAYS} -delete"
|
else
|
||||||
RET=$?
|
RET=$?
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $RET -ne 0 ]]; then
|
if [[ $RET -ne 0 ]]; then
|
||||||
log "ERROR: remote rotation failed for users"
|
log "ERROR: remote rotation failed for users"
|
||||||
@@ -502,8 +533,11 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
for DB in "${DBS_ARRAY[@]}"; do
|
for DB in "${DBS_ARRAY[@]}"; do
|
||||||
ssh "${SSH_OPTS[@]}" "$IA_SSH" "find '${BACKUP_REMOTE_DIR}/${DB}' -type f -name '${DB}_*.dump' -mtime +${RETENTION_DAYS} -delete"
|
if ssh "${SSH_OPTS[@]}" "$IA_SSH" "find '${BACKUP_REMOTE_DIR}/${DB}' -type f -name '${DB}_*.dump' -mtime +${RETENTION_DAYS} -delete"; then
|
||||||
RET=$?
|
RET=0
|
||||||
|
else
|
||||||
|
RET=$?
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $RET -ne 0 ]]; then
|
if [[ $RET -ne 0 ]]; then
|
||||||
log "ERROR: remote rotation failed for ${DB}"
|
log "ERROR: remote rotation failed for ${DB}"
|
||||||
@@ -512,8 +546,6 @@ for DB in "${DBS_ARRAY[@]}"; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
log "Remote rotation finished"
|
log "Remote rotation finished"
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ add_summary_line() {
|
|||||||
#######################################
|
#######################################
|
||||||
# Envoi du message Discord récapitulatif
|
# Envoi du message Discord récapitulatif
|
||||||
#######################################
|
#######################################
|
||||||
send_discord_summary() {
|
send_discord() {
|
||||||
[[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0
|
[[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0
|
||||||
|
|
||||||
local header_icon ping_prefix=""
|
local header_icon ping_prefix=""
|
||||||
@@ -154,7 +154,7 @@ send_discord_summary() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
local payload
|
local payload
|
||||||
payload="$(jq -n --arg content "$msg" '{content: $content}')"
|
payload="$(jq -n --arg content "$msg" '{content: $content}')" || return 0
|
||||||
|
|
||||||
curl -fsS -H "Content-Type: application/json" \
|
curl -fsS -H "Content-Type: application/json" \
|
||||||
-d "$payload" \
|
-d "$payload" \
|
||||||
@@ -228,7 +228,7 @@ main() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
FAILURES="$failures"
|
FAILURES="$failures"
|
||||||
send_discord_summary
|
send_discord
|
||||||
|
|
||||||
if [[ "$failures" -gt 0 ]]; then
|
if [[ "$failures" -gt 0 ]]; then
|
||||||
exit 2
|
exit 2
|
||||||
|
|||||||
@@ -120,6 +120,10 @@ cleanup() {
|
|||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
require_cmd() {
|
require_cmd() {
|
||||||
|
command -v "$1" >/dev/null 2>&1 || fail "commande requise absente : $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
has_cmd() {
|
||||||
command -v "$1" >/dev/null 2>&1
|
command -v "$1" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,11 +134,10 @@ sql_escape_literal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate_db_name() {
|
validate_db_name() {
|
||||||
local db_name="$1"
|
local db_name="${1:-}"
|
||||||
|
|
||||||
[[ -n "$db_name" ]] || fail "nom de base vide"
|
[[ -n "$db_name" ]] || return 1
|
||||||
[[ "$db_name" =~ ^[A-Za-z0-9_]+$ ]] || \
|
[[ "$db_name" =~ ^[a-zA-Z0-9_]+$ ]] || return 1
|
||||||
fail "nom de base invalide : seuls les lettres, chiffres et underscores sont autorisés"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build_excluded_roles_regex() {
|
build_excluded_roles_regex() {
|
||||||
@@ -158,29 +161,20 @@ build_excluded_roles_regex() {
|
|||||||
# Envoi simple d'un message texte via webhook Discord.
|
# Envoi simple d'un message texte via webhook Discord.
|
||||||
# Si DISCORD_WEBHOOK_URL n'est pas défini, on ignore silencieusement l'envoi.
|
# Si DISCORD_WEBHOOK_URL n'est pas défini, on ignore silencieusement l'envoi.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
send_discord_message() {
|
send_discord() {
|
||||||
local message="$1"
|
local message="$1"
|
||||||
local payload=""
|
local payload=""
|
||||||
|
|
||||||
[[ -n "$DISCORD_WEBHOOK_URL" ]] || {
|
[[ -n "$DISCORD_WEBHOOK_URL" ]] || return 0
|
||||||
log "DISCORD_WEBHOOK_URL non défini : notification Discord ignorée."
|
has_cmd jq || return 0
|
||||||
return 0
|
has_cmd curl || return 0
|
||||||
}
|
|
||||||
|
|
||||||
if ! require_cmd curl; then
|
payload="$(jq -n --arg content "$message" '{content: $content}')" || return 0
|
||||||
log "curl absent : notification Discord ignorée."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
payload="$(jq -n --arg content "$message" '{content: $content}')" || {
|
curl -fsS "$DISCORD_WEBHOOK_URL" \
|
||||||
log "Impossible de construire le payload JSON Discord."
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
curl -sS -X POST "$DISCORD_WEBHOOK_URL" \
|
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$payload" \
|
-d "$payload" \
|
||||||
>/dev/null || log "Échec d'envoi de la notification Discord."
|
>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -188,6 +182,7 @@ send_discord_message() {
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
[[ -f "$SSH_KEY" ]] || fail "clé SSH introuvable : $SSH_KEY"
|
[[ -f "$SSH_KEY" ]] || fail "clé SSH introuvable : $SSH_KEY"
|
||||||
[[ -r "$SSH_KEY" ]] || fail "clé SSH non lisible : $SSH_KEY"
|
[[ -r "$SSH_KEY" ]] || fail "clé SSH non lisible : $SSH_KEY"
|
||||||
|
[[ ! -L "$SSH_KEY" ]] || fail "clé SSH ne doit pas être un lien symbolique : $SSH_KEY"
|
||||||
[[ "$PGPORT" =~ ^[0-9]+$ ]] || fail "PGPORT invalide"
|
[[ "$PGPORT" =~ ^[0-9]+$ ]] || fail "PGPORT invalide"
|
||||||
[[ "$BACKUP_REMOTE_SSH_PORT" =~ ^[0-9]+$ ]] || fail "BACKUP_REMOTE_SSH_PORT invalide"
|
[[ "$BACKUP_REMOTE_SSH_PORT" =~ ^[0-9]+$ ]] || fail "BACKUP_REMOTE_SSH_PORT invalide"
|
||||||
[[ "$PGUSER" =~ ^[a-zA-Z0-9_][a-zA-Z0-9_-]*$ ]] || fail "PGUSER invalide"
|
[[ "$PGUSER" =~ ^[a-zA-Z0-9_][a-zA-Z0-9_-]*$ ]] || fail "PGUSER invalide"
|
||||||
@@ -221,7 +216,7 @@ REMOTE_SSH="${BACKUP_REMOTE_USER}@${BACKUP_REMOTE_HOST}"
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
POSTGRES_INSTALLED=false
|
POSTGRES_INSTALLED=false
|
||||||
|
|
||||||
if ! require_cmd psql || ! require_cmd pg_restore || ! require_cmd createdb || ! require_cmd dropdb; then
|
if ! has_cmd psql || ! has_cmd pg_restore || ! has_cmd createdb || ! has_cmd dropdb; then
|
||||||
log "PostgreSQL absent : installation en cours..."
|
log "PostgreSQL absent : installation en cours..."
|
||||||
|
|
||||||
sudo apt update >>"$LOG_FILE" 2>&1 || fail "échec de apt update"
|
sudo apt update >>"$LOG_FILE" 2>&1 || fail "échec de apt update"
|
||||||
@@ -248,15 +243,17 @@ fi
|
|||||||
# Attente disponibilité PostgreSQL
|
# Attente disponibilité PostgreSQL
|
||||||
###############################################################################
|
###############################################################################
|
||||||
log "Vérification de la disponibilité de PostgreSQL..."
|
log "Vérification de la disponibilité de PostgreSQL..."
|
||||||
|
PG_READY=false
|
||||||
for _ in {1..20}; do
|
for _ in {1..20}; do
|
||||||
if sudo -u postgres psql -d postgres -c "SELECT 1;" >/dev/null 2>&1; then
|
if sudo -u postgres psql -d postgres -c "SELECT 1;" >/dev/null 2>&1; then
|
||||||
|
PG_READY=true
|
||||||
log "PostgreSQL répond correctement."
|
log "PostgreSQL répond correctement."
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
if ! sudo -u postgres psql -d postgres -c "SELECT 1;" >/dev/null 2>&1; then
|
if [[ "$PG_READY" != true ]]; then
|
||||||
fail "PostgreSQL ne répond pas correctement"
|
fail "PostgreSQL ne répond pas correctement"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -303,7 +300,7 @@ else
|
|||||||
read -r -p "Nom exact de la base à restaurer : " DB
|
read -r -p "Nom exact de la base à restaurer : " DB
|
||||||
fi
|
fi
|
||||||
|
|
||||||
validate_db_name "$DB"
|
validate_db_name "$DB" || fail "nom de base invalide"
|
||||||
|
|
||||||
log "Environnement : $ENV_NAME"
|
log "Environnement : $ENV_NAME"
|
||||||
log "Base cible sélectionnée : $DB"
|
log "Base cible sélectionnée : $DB"
|
||||||
@@ -424,6 +421,8 @@ if [[ -n "$LOCAL_ROLES_FILE" ]]; then
|
|||||||
cp "$LOCAL_ROLES_FILE" "$FILTERED_ROLES_FILE"
|
cp "$LOCAL_ROLES_FILE" "$FILTERED_ROLES_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
sed -i -E '/^ALTER ROLE .* (NO)?SUPERUSER\b/d' "$FILTERED_ROLES_FILE"
|
||||||
|
|
||||||
log "Fichier des rôles filtré généré : ${FILTERED_ROLES_FILE}"
|
log "Fichier des rôles filtré généré : ${FILTERED_ROLES_FILE}"
|
||||||
|
|
||||||
sed -nE 's/^CREATE ROLE "?([^" ;]+)"?;$/\1/p' "$FILTERED_ROLES_FILE" \
|
sed -nE 's/^CREATE ROLE "?([^" ;]+)"?;$/\1/p' "$FILTERED_ROLES_FILE" \
|
||||||
@@ -504,4 +503,4 @@ Hôte PostgreSQL : ${PGHOST}:${PGPORT}
|
|||||||
Dump utilisé : $(basename "$LAST_REMOTE_DB_DUMP")
|
Dump utilisé : $(basename "$LAST_REMOTE_DB_DUMP")
|
||||||
Log : ${LOG_FILE}"
|
Log : ${LOG_FILE}"
|
||||||
|
|
||||||
send_discord_message "$SUCCESS_MESSAGE"
|
send_discord "$SUCCESS_MESSAGE"
|
||||||
|
|||||||
Reference in New Issue
Block a user