Files
Malio-ops/RebuildBdd/Checkup/check-postgresql.sh
2026-03-19 09:57:12 +01:00

227 lines
6.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
DEFAULT_ENV_FILE="${REPO_DIR}/.env"
ENV_FILE="${ENV_FILE:-$DEFAULT_ENV_FILE}"
CLI_REQUEST_ID=""
NON_INTERACTIVE="${NON_INTERACTIVE:-no}"
while [[ $# -gt 0 ]]; do
case "$1" in
--env-file)
[[ $# -ge 2 ]] || { echo "Argument manquant pour --env-file" >&2; exit 1; }
ENV_FILE="$2"
shift 2
;;
--request-id)
[[ $# -ge 2 ]] || { echo "Argument manquant pour --request-id" >&2; exit 1; }
CLI_REQUEST_ID="$2"
shift 2
;;
--non-interactive)
NON_INTERACTIVE="yes"
shift
;;
*)
echo "Argument inconnu : $1" >&2
exit 1
;;
esac
done
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
fail() {
log "ERROR: $*" >&2
exit 1
}
has_cmd() {
command -v "$1" >/dev/null 2>&1
}
postgres_server_ready() {
has_cmd postgres || return 1
has_cmd pg_ctlcluster || return 1
has_cmd pg_lsclusters || return 1
return 0
}
ensure_postgres_cluster() {
if ! has_cmd pg_lsclusters || ! has_cmd pg_createcluster; then
return 0
fi
if pg_lsclusters --no-header 2>/dev/null | grep -q .; then
return 0
fi
local version=""
if [[ -d /etc/postgresql ]]; then
version="$(find /etc/postgresql -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | LC_ALL=C sort -V | tail -n 1)"
fi
if [[ -z "$version" ]] && has_cmd psql; then
version="$(psql --version 2>/dev/null | awk '{print $3}' | cut -d. -f1)"
fi
[[ -n "$version" ]] || return 1
log "Aucun cluster PostgreSQL détecté, création de ${version}/main..."
"$SUDO_BIN" pg_createcluster "$version" main --start >/dev/null 2>&1 || return 1
return 0
}
collect_postgres_diagnostics() {
local diagnostics=""
if "$SUDO_BIN" systemctl status "$POSTGRES_SERVICE_NAME" --no-pager >/dev/null 2>&1; then
diagnostics+="systemctl status ${POSTGRES_SERVICE_NAME}: OK; "
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' ' ' ); "
fi
if has_cmd pg_lsclusters; then
diagnostics+="pg_lsclusters: $(pg_lsclusters --no-header 2>/dev/null | tr '\n' ' '); "
fi
if has_cmd journalctl; then
diagnostics+="journalctl: $( "$SUDO_BIN" journalctl -u "$POSTGRES_SERVICE_NAME" -n 10 --no-pager 2>/dev/null | tr '\n' ' ' ); "
fi
printf '%s' "${diagnostics% }"
}
start_postgres_service() {
if "$SUDO_BIN" systemctl start "$POSTGRES_SERVICE_NAME" >/dev/null 2>&1; then
return 0
fi
if has_cmd service && "$SUDO_BIN" service "$POSTGRES_SERVICE_NAME" start >/dev/null 2>&1; then
return 0
fi
if has_cmd pg_lsclusters && has_cmd pg_ctlcluster; then
local version cluster
while read -r version cluster _; do
[[ -n "$version" && -n "$cluster" ]] || continue
if "$SUDO_BIN" pg_ctlcluster "$version" "$cluster" start >/dev/null 2>&1; then
return 0
fi
done < <(pg_lsclusters --no-header 2>/dev/null || true)
fi
return 1
}
[[ -f "$ENV_FILE" ]] || fail "fichier .env introuvable : $ENV_FILE"
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
: "${PGHOST:?Variable PGHOST manquante}"
: "${PGPORT:?Variable PGPORT manquante}"
: "${PGUSER:?Variable PGUSER manquante}"
: "${PGPASSWORD:?Variable PGPASSWORD manquante}"
AUTO_INSTALL_POSTGRES="${AUTO_INSTALL_POSTGRES:-yes}"
AUTO_CREATE_PGUSER="${AUTO_CREATE_PGUSER:-yes}"
PGUSER_SUPERUSER="${PGUSER_SUPERUSER:-no}"
POSTGRES_PACKAGE_LIST="${POSTGRES_PACKAGE_LIST:-postgresql postgresql-client postgresql-contrib}"
POSTGRES_SERVICE_NAME="${POSTGRES_SERVICE_NAME:-postgresql}"
SUDO_BIN="${SUDO_BIN:-sudo}"
read -r -a POSTGRES_PACKAGES <<< "$POSTGRES_PACKAGE_LIST"
[[ "${#POSTGRES_PACKAGES[@]}" -gt 0 ]] || fail "POSTGRES_PACKAGE_LIST vide"
export PGPASSWORD
if ! has_cmd "$SUDO_BIN"; then
fail "sudo absent sur la cible"
fi
if ! "$SUDO_BIN" /usr/bin/systemctl --version >/dev/null 2>&1; then
fail "sudo indisponible pour systemctl"
fi
if [[ ! "$PGPORT" =~ ^[0-9]+$ ]]; then
fail "PGPORT invalide : $PGPORT"
fi
POSTGRES_INSTALLED="no"
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"
log "PostgreSQL absent : installation en cours..."
"$SUDO_BIN" apt update >/dev/null 2>&1 || fail "échec de apt update"
"$SUDO_BIN" apt install -y "${POSTGRES_PACKAGES[@]}" >/dev/null 2>&1 || fail "échec de l'installation PostgreSQL"
POSTGRES_INSTALLED="yes"
log "Installation PostgreSQL terminée."
else
log "PostgreSQL déjà installé."
fi
ensure_postgres_cluster || fail "aucun cluster PostgreSQL disponible et création automatique impossible"
if ! "$SUDO_BIN" systemctl is-active --quiet "$POSTGRES_SERVICE_NAME"; then
log "Démarrage du service PostgreSQL..."
if ! start_postgres_service; then
fail "impossible de démarrer PostgreSQL. $(collect_postgres_diagnostics)"
fi
else
log "Service PostgreSQL déjà actif."
fi
log "Vérification de la disponibilité de PostgreSQL..."
PG_READY=false
for _ in {1..20}; do
if "$SUDO_BIN" -u postgres psql -d postgres -c "SELECT 1;" >/dev/null 2>&1; then
PG_READY=true
log "PostgreSQL répond correctement."
break
fi
sleep 1
done
if [[ "$PG_READY" != true ]]; then
fail "PostgreSQL ne répond pas correctement"
fi
if [[ "${AUTO_CREATE_PGUSER,,}" == "yes" ]]; then
ROLE_EXISTS="$(
"$SUDO_BIN" -u postgres psql -d postgres -tAc \
"SELECT 1 FROM pg_roles WHERE rolname='${PGUSER//\'/\'\'}'" 2>/dev/null || true
)"
if [[ "$ROLE_EXISTS" != "1" ]]; then
log "Création du rôle PostgreSQL ${PGUSER}..."
ROLE_ATTRIBUTES="LOGIN CREATEDB CREATEROLE"
if [[ "${PGUSER_SUPERUSER,,}" == "yes" ]]; then
ROLE_ATTRIBUTES="LOGIN SUPERUSER CREATEDB CREATEROLE"
fi
"$SUDO_BIN" -u postgres psql -d postgres -c \
"CREATE ROLE \"${PGUSER}\" WITH ${ROLE_ATTRIBUTES} PASSWORD '${PGPASSWORD//\'/\'\'}';" \
>/dev/null 2>&1 || fail "échec de création du rôle ${PGUSER}"
log "Rôle PostgreSQL ${PGUSER} créé."
else
log "Rôle PostgreSQL ${PGUSER} déjà présent."
fi
fi
if ! psql -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -d postgres -c "SELECT 1;" >/dev/null 2>&1; then
fail "connexion PostgreSQL locale impossible avec PGUSER=${PGUSER}"
fi
log "Check PostgreSQL terminé avec succès."