304 lines
9.3 KiB
Bash
304 lines
9.3 KiB
Bash
#!/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:-<empty>}" ;;
|
||
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 <<EOF
|
||
ВНИМАНИЕ: скрипт настроен на удаление данных и/или каталогов Postgres Pro.
|
||
Это действие необратимо.
|
||
|
||
Если вы уверены, введите: DELETE
|
||
EOF
|
||
read -r answer
|
||
[[ "$answer" == "DELETE" ]] || fail "Подтверждение не получено, удаление отменено"
|
||
fi
|
||
}
|
||
|
||
run_pgsetup_service() {
|
||
local action="$1"
|
||
|
||
if [[ -x "$PGSETUP" ]]; then
|
||
if "$PGSETUP" service "$action" >/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:-<empty>}"
|
||
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 <<EOF
|
||
|
||
Удаление завершено.
|
||
|
||
Что сделано:
|
||
- остановка сервиса: ${UNINSTALL_STOP_SERVICE};
|
||
- отключение автозапуска: ${UNINSTALL_DISABLE_SERVICE};
|
||
- purge пакетов: ${UNINSTALL_PURGE_PACKAGES};
|
||
- autoremove: ${UNINSTALL_AUTOREMOVE};
|
||
- удаление APT-репозитория: ${UNINSTALL_REMOVE_REPO};
|
||
- удаление auth-файла репозитория: ${UNINSTALL_REMOVE_AUTH_FILE};
|
||
- удаление GPG-ключа репозитория: ${UNINSTALL_REMOVE_GPG_KEY};
|
||
- удаление /etc/default-файла инстанса: ${UNINSTALL_REMOVE_DEFAULT_FILE};
|
||
- удаление каталога данных: ${UNINSTALL_REMOVE_DATA_DIR}${data_dir:+ (${data_dir})};
|
||
- удаление каталога /var/lib/pgpro/1c-18: ${UNINSTALL_REMOVE_LOG_DIR};
|
||
- удаление каталога /opt/pgpro/1c-18: ${UNINSTALL_REMOVE_HOME_DIRS}.
|
||
|
||
Проверки:
|
||
systemctl status ${SERVICE_NAME} || true
|
||
dpkg -l | grep postgrespro || true
|
||
ls -la /etc/apt/sources.list.d/ | grep postgresql-1c-18 || true
|
||
EOF
|
||
}
|
||
|
||
main() {
|
||
require_root
|
||
need_cmd apt-get
|
||
need_cmd dpkg-query
|
||
need_cmd sed
|
||
need_cmd grep
|
||
need_cmd rm
|
||
need_cmd runuser
|
||
|
||
load_env
|
||
check_os
|
||
confirm_destructive_actions
|
||
|
||
if [[ "$UNINSTALL_STOP_SERVICE" == "true" ]]; then
|
||
run_pgsetup_service stop
|
||
fi
|
||
|
||
if [[ "$UNINSTALL_DISABLE_SERVICE" == "true" ]]; then
|
||
run_pgsetup_service disable
|
||
fi
|
||
|
||
remove_packages
|
||
remove_repo_files
|
||
remove_data_and_logs
|
||
show_summary
|
||
}
|
||
|
||
main "$@"
|