#!/usr/bin/env bash set -Eeuo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="${ENV_FILE:-${SCRIPT_DIR}/.env}" log() { printf '[%s] %s\n' "$(date '+%F %T')" "$*" } fail() { printf 'ERROR: %s\n' "$*" >&2 exit 1 } need_cmd() { command -v "$1" >/dev/null 2>&1 || fail "Не найдена команда: $1" } bool_norm() { case "${1:-}" in 1|true|TRUE|yes|YES|on|ON) echo "true" ;; 0|false|FALSE|no|NO|off|OFF) echo "false" ;; *) fail "Неверное булево значение: ${1:-}" ;; esac } require_root() { [[ "$(id -u)" -eq 0 ]] || fail "Скрипт нужно запускать от root" } load_env() { [[ -f "$ENV_FILE" ]] || fail "Файл окружения не найден: $ENV_FILE" set -a # shellcheck disable=SC1090 . "$ENV_FILE" set +a : "${PGPRO_BIN_DIR:?В .env должна быть переменная PGPRO_BIN_DIR}" : "${SERVICE_NAME:?В .env должна быть переменная SERVICE_NAME}" : "${PACKAGE_STANDALONE:?В .env должна быть переменная PACKAGE_STANDALONE}" : "${PACKAGE_PARALLEL:?В .env должна быть переменная PACKAGE_PARALLEL}" REPO_LIST_FILE="${REPO_LIST_FILE:-/etc/apt/sources.list.d/postgresql-1c-18.list}" REPO_AUTH_FILE="${REPO_AUTH_FILE:-/etc/apt/auth.conf.d/repo.postgrespro.ru.conf}" REPO_GPG_FILE="${REPO_GPG_FILE:-/etc/apt/trusted.gpg.d/postgrespro.gpg}" DEFAULT_DATA_DIR="${DEFAULT_DATA_DIR:-/var/lib/pgpro/1c-18/data}" DEFAULT_ETC_FILE="${DEFAULT_ETC_FILE:-/etc/default/${SERVICE_NAME}}" POSTGRES_SOCKET_DIR="${POSTGRES_SOCKET_DIR:-/var/run/postgresql}" UNINSTALL_DISABLE_SERVICE="$(bool_norm "${UNINSTALL_DISABLE_SERVICE:-true}")" UNINSTALL_STOP_SERVICE="$(bool_norm "${UNINSTALL_STOP_SERVICE:-true}")" UNINSTALL_PURGE_PACKAGES="$(bool_norm "${UNINSTALL_PURGE_PACKAGES:-true}")" UNINSTALL_AUTOREMOVE="$(bool_norm "${UNINSTALL_AUTOREMOVE:-true}")" UNINSTALL_REMOVE_REPO="$(bool_norm "${UNINSTALL_REMOVE_REPO:-true}")" UNINSTALL_REMOVE_AUTH_FILE="$(bool_norm "${UNINSTALL_REMOVE_AUTH_FILE:-true}")" UNINSTALL_REMOVE_GPG_KEY="$(bool_norm "${UNINSTALL_REMOVE_GPG_KEY:-true}")" UNINSTALL_REMOVE_DEFAULT_FILE="$(bool_norm "${UNINSTALL_REMOVE_DEFAULT_FILE:-false}")" UNINSTALL_REMOVE_DATA_DIR="$(bool_norm "${UNINSTALL_REMOVE_DATA_DIR:-false}")" UNINSTALL_REMOVE_LOG_DIR="$(bool_norm "${UNINSTALL_REMOVE_LOG_DIR:-false}")" UNINSTALL_REMOVE_HOME_DIRS="$(bool_norm "${UNINSTALL_REMOVE_HOME_DIRS:-false}")" UNINSTALL_FORCE="$(bool_norm "${UNINSTALL_FORCE:-false}")" PGPRO_DATA_DIR="${PGPRO_DATA_DIR:-}" PGSETUP="${PGPRO_BIN_DIR}/pg-setup" PSQL="${PGPRO_BIN_DIR}/psql" } check_os() { [[ -f /etc/os-release ]] || fail "Не найден /etc/os-release" # shellcheck disable=SC1091 . /etc/os-release [[ "${ID:-}" == "debian" ]] || fail "Скрипт рассчитан на Debian. Найдено: ${ID:-unknown}" [[ "${VERSION_ID:-}" == "13" ]] || fail "Скрипт рассчитан на Debian 13. Найдено: ${VERSION_ID:-unknown}" } confirm_destructive_actions() { if [[ "$UNINSTALL_FORCE" == "true" ]]; then return 0 fi if [[ "$UNINSTALL_REMOVE_DATA_DIR" == "true" || "$UNINSTALL_REMOVE_LOG_DIR" == "true" || "$UNINSTALL_REMOVE_HOME_DIRS" == "true" ]]; then cat </dev/null 2>&1; then log "Выполнено: pg-setup service $action" return 0 fi fi if command -v systemctl >/dev/null 2>&1; then case "$action" in stop) systemctl stop "$SERVICE_NAME" >/dev/null 2>&1 || true ;; disable) systemctl disable "$SERVICE_NAME" >/dev/null 2>&1 || true ;; status) systemctl status "$SERVICE_NAME" --no-pager || true ;; esac fi } detect_data_dir_from_server() { if [[ -x "$PSQL" ]]; then if runuser -u postgres -- "$PSQL" -v ON_ERROR_STOP=1 -h "$POSTGRES_SOCKET_DIR" -d postgres -Atqc "SHOW data_directory;" 2>/dev/null; then return 0 fi fi return 1 } detect_data_dir() { if [[ -n "$PGPRO_DATA_DIR" ]]; then printf '%s\n' "$PGPRO_DATA_DIR" return 0 fi if [[ -f "$DEFAULT_ETC_FILE" ]]; then local from_default from_default="$(sed -n 's/^PGDATA=//p' "$DEFAULT_ETC_FILE" | tail -n1)" if [[ -n "$from_default" ]]; then printf '%s\n' "$from_default" return 0 fi fi if detect_data_dir_from_server >/dev/null 2>&1; then detect_data_dir_from_server return 0 fi printf '%s\n' "$DEFAULT_DATA_DIR" } remove_packages() { [[ "$UNINSTALL_PURGE_PACKAGES" == "true" ]] || { log "Удаление пакетов отключено: UNINSTALL_PURGE_PACKAGES=false" return 0 } export DEBIAN_FRONTEND=noninteractive local pkgs=() local pkg for pkg in "$PACKAGE_STANDALONE" "$PACKAGE_PARALLEL"; do if dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q 'install ok installed'; then pkgs+=("$pkg") fi done if [[ ${#pkgs[@]} -eq 0 ]]; then log "Пакеты PostgreSQL for 1C 18 не найдены, purge пропускаю" else log "Удаляю пакеты: ${pkgs[*]}" apt-get purge -y "${pkgs[@]}" fi if [[ "$UNINSTALL_AUTOREMOVE" == "true" ]]; then log "Запускаю apt-get autoremove" apt-get autoremove -y --purge fi } remove_repo_files() { local touched=false if [[ "$UNINSTALL_REMOVE_REPO" == "true" && -f "$REPO_LIST_FILE" ]]; then rm -f "$REPO_LIST_FILE" log "Удален файл репозитория: $REPO_LIST_FILE" touched=true fi if [[ "$UNINSTALL_REMOVE_AUTH_FILE" == "true" && -f "$REPO_AUTH_FILE" ]]; then rm -f "$REPO_AUTH_FILE" log "Удален auth-файл APT: $REPO_AUTH_FILE" touched=true fi if [[ "$UNINSTALL_REMOVE_GPG_KEY" == "true" && -f "$REPO_GPG_FILE" ]]; then rm -f "$REPO_GPG_FILE" log "Удален GPG-ключ репозитория: $REPO_GPG_FILE" touched=true fi if [[ "$UNINSTALL_REMOVE_DEFAULT_FILE" == "true" && -f "$DEFAULT_ETC_FILE" ]]; then rm -f "$DEFAULT_ETC_FILE" log "Удален файл настроек инстанса: $DEFAULT_ETC_FILE" touched=true fi if [[ "$touched" == true ]]; then apt-get update || true fi } remove_data_and_logs() { local data_dir data_dir="$(detect_data_dir)" if [[ "$UNINSTALL_REMOVE_DATA_DIR" == "true" ]]; then if [[ -n "$data_dir" && -d "$data_dir" ]]; then rm -rf --one-file-system "$data_dir" log "Удален каталог данных: $data_dir" else log "Каталог данных не найден, удаление пропускаю: ${data_dir:-}" fi fi if [[ "$UNINSTALL_REMOVE_LOG_DIR" == "true" ]]; then local log_dir="/var/lib/pgpro/1c-18" if [[ -d "$log_dir" ]]; then rm -rf --one-file-system "$log_dir" log "Удален каталог логов/служебных файлов: $log_dir" else log "Каталог логов не найден, удаление пропускаю: $log_dir" fi fi if [[ "$UNINSTALL_REMOVE_HOME_DIRS" == "true" ]]; then local opt_dir="/opt/pgpro/1c-18" if [[ -d "$opt_dir" ]]; then rm -rf --one-file-system "$opt_dir" log "Удален каталог /opt: $opt_dir" else log "Каталог /opt не найден, удаление пропускаю: $opt_dir" fi fi } show_summary() { local data_dir data_dir="$(detect_data_dir)" cat <