Загрузить файлы в «/»

This commit is contained in:
2026-03-25 10:03:07 +00:00
commit 37f3a94994
4 changed files with 583 additions and 0 deletions

326
install_pg1c.sh Normal file
View File

@@ -0,0 +1,326 @@
#!/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
' "$(date '+%F %T')" "$*"
}
fail() {
printf 'ERROR: %s
' "$*" >&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
: "${REPO_ADD_URL:?В .env должна быть переменная REPO_ADD_URL}"
: "${PGPRO_BIN_DIR:?В .env должна быть переменная PGPRO_BIN_DIR}"
: "${SERVICE_NAME:?В .env должна быть переменная SERVICE_NAME}"
: "${PACKAGE_STANDALONE:?В .env должна быть переменная PACKAGE_STANDALONE}"
: "${PACKAGE_PARALLEL:?В .env должна быть переменная PACKAGE_PARALLEL}"
: "${PG_ADMIN_USER:?В .env должна быть переменная PG_ADMIN_USER}"
: "${PG_ADMIN_PASSWORD:?В .env должна быть переменная PG_ADMIN_PASSWORD}"
INSTALL_MODE="${INSTALL_MODE:-standalone}"
PG_ADMIN_SUPERUSER="$(bool_norm "${PG_ADMIN_SUPERUSER:-true}")"
PG_CREATE_DB="$(bool_norm "${PG_CREATE_DB:-false}")"
PG_SERVICE_ENABLE="$(bool_norm "${PG_SERVICE_ENABLE:-true}")"
PG_SERVICE_START="$(bool_norm "${PG_SERVICE_START:-true}")"
ENFORCE_PASSWORD_AUTH="$(bool_norm "${ENFORCE_PASSWORD_AUTH:-true}")"
REPLACE_LOCAL_PEER_WITH="${REPLACE_LOCAL_PEER_WITH:-scram-sha-256}"
REPLACE_HOST_AUTH_WITH="${REPLACE_HOST_AUTH_WITH:-scram-sha-256}"
CREATE_HBA_BACKUP="$(bool_norm "${CREATE_HBA_BACKUP:-true}")"
POSTGRES_SOCKET_DIR="${POSTGRES_SOCKET_DIR:-/var/run/postgresql}"
PG_DB_NAME="${PG_DB_NAME:-}"
REPO_ADD_TMP="${REPO_ADD_TMP:-/tmp/pgpro-repo-add.sh}"
case "$INSTALL_MODE" in
standalone|parallel) ;;
*) fail "INSTALL_MODE должен быть standalone или parallel" ;;
esac
case "$REPLACE_LOCAL_PEER_WITH" in
scram-sha-256|md5|password|trust) ;;
*) fail "REPLACE_LOCAL_PEER_WITH должен быть scram-sha-256, md5, password или trust" ;;
esac
case "$REPLACE_HOST_AUTH_WITH" in
scram-sha-256|md5|password|trust) ;;
*) fail "REPLACE_HOST_AUTH_WITH должен быть scram-sha-256, md5, password или trust" ;;
esac
if [[ "$PG_CREATE_DB" == "true" && -z "$PG_DB_NAME" ]]; then
fail "Если PG_CREATE_DB=true, нужно указать PG_DB_NAME"
fi
PSQL="${PGPRO_BIN_DIR}/psql"
PGSETUP="${PGPRO_BIN_DIR}/pg-setup"
PG_ISREADY="${PGPRO_BIN_DIR}/pg_isready"
}
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}"
}
ensure_base_packages() {
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y wget ca-certificates gnupg apt-transport-https sed grep coreutils
}
ensure_repo() {
if [[ -f /etc/apt/sources.list.d/postgresql-1c-18.list ]]; then
log "Репозиторий PostgreSQL for 1C 18 уже добавлен"
apt-get update
return
fi
log "Скачиваю vendor-скрипт добавления репозитория"
wget -O "$REPO_ADD_TMP" "$REPO_ADD_URL"
chmod +x "$REPO_ADD_TMP"
sh "$REPO_ADD_TMP"
rm -f "$REPO_ADD_TMP"
}
install_pgpro() {
export DEBIAN_FRONTEND=noninteractive
if [[ "$INSTALL_MODE" == "standalone" ]]; then
log "Устанавливаю пакет ${PACKAGE_STANDALONE}"
apt-get install -y "$PACKAGE_STANDALONE"
else
log "Устанавливаю пакет ${PACKAGE_PARALLEL} для параллельной установки"
apt-get install -y "$PACKAGE_PARALLEL"
[[ -x "$PGSETUP" ]] || fail "Не найден $PGSETUP"
if [[ ! -d /var/lib/pgpro/1c-18/data/base ]]; then
log "Инициализирую новый кластер Postgres Pro 1C 18"
"$PGSETUP" initdb
else
log "Кластер уже инициализирован, initdb пропускаю"
fi
fi
}
enable_and_start_service() {
if ! systemctl list-unit-files | grep -q "^${SERVICE_NAME}\.service"; then
fail "Не найден unit-файл ${SERVICE_NAME}.service"
fi
if [[ "$PG_SERVICE_ENABLE" == "true" ]]; then
log "Включаю автозапуск ${SERVICE_NAME}"
systemctl enable "$SERVICE_NAME"
fi
if [[ "$PG_SERVICE_START" == "true" ]]; then
log "Запускаю ${SERVICE_NAME}"
systemctl restart "$SERVICE_NAME"
fi
}
wait_for_postgres() {
[[ -x "$PG_ISREADY" ]] || fail "Не найден $PG_ISREADY"
log "Жду готовности PostgreSQL"
local i
for i in {1..30}; do
if runuser -u postgres -- "$PG_ISREADY" -h "$POSTGRES_SOCKET_DIR" -d postgres >/dev/null 2>&1; then
return 0
fi
sleep 1
done
systemctl status "$SERVICE_NAME" --no-pager || true
fail "PostgreSQL не поднялся за ожидаемое время"
}
psql_postgres() {
runuser -u postgres -- "$PSQL" -v ON_ERROR_STOP=1 -h "$POSTGRES_SOCKET_DIR" -d postgres "$@"
}
configure_role() {
[[ -x "$PSQL" ]] || fail "Не найден $PSQL"
log "Создаю или обновляю роль ${PG_ADMIN_USER}"
local role_attr="LOGIN"
if [[ "$PG_ADMIN_SUPERUSER" == "true" ]]; then
role_attr+=" SUPERUSER"
else
role_attr+=" NOSUPERUSER CREATEDB CREATEROLE"
fi
local safe_user safe_pass
safe_user="${PG_ADMIN_USER//'/''}"
safe_pass="${PG_ADMIN_PASSWORD//'/''}"
psql_postgres <<SQL
DO \$do\$
BEGIN
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = '${safe_user}') THEN
EXECUTE format('ALTER ROLE %I WITH ${role_attr} PASSWORD %L', '${safe_user}', '${safe_pass}');
ELSE
EXECUTE format('CREATE ROLE %I WITH ${role_attr} PASSWORD %L', '${safe_user}', '${safe_pass}');
END IF;
END
\$do\$;
SQL
}
configure_database() {
[[ "$PG_CREATE_DB" == "true" ]] || return 0
log "Создаю базу ${PG_DB_NAME}, если она отсутствует"
local safe_db safe_user
safe_db="${PG_DB_NAME//'/''}"
safe_user="${PG_ADMIN_USER//'/''}"
psql_postgres <<SQL
SELECT 'CREATE DATABASE "' || replace('${safe_db}', '"', '""') || '" OWNER "' || replace('${safe_user}', '"', '""') || '"'
WHERE NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = '${safe_db}')
\gexec
SQL
}
detect_hba_file() {
psql_postgres -Atqc "SHOW hba_file;"
}
backup_hba_if_needed() {
local hba_file="$1"
if [[ "$CREATE_HBA_BACKUP" == "true" ]]; then
local backup_file="${hba_file}.bak.$(date +%Y%m%d_%H%M%S)"
cp -a "$hba_file" "$backup_file"
log "Создан бэкап pg_hba.conf: $backup_file"
fi
}
configure_pg_hba() {
[[ "$ENFORCE_PASSWORD_AUTH" == "true" ]] || {
log "Правка pg_hba.conf отключена: ENFORCE_PASSWORD_AUTH=false"
return 0
}
local hba_file
hba_file="$(detect_hba_file)"
[[ -n "$hba_file" ]] || fail "Не удалось определить путь к pg_hba.conf"
[[ -f "$hba_file" ]] || fail "Файл pg_hba.conf не найден: $hba_file"
log "Настраиваю парольную аутентификацию в $hba_file"
backup_hba_if_needed "$hba_file"
local tmp_file
tmp_file="$(mktemp)"
awk -v local_method="$REPLACE_LOCAL_PEER_WITH" -v host_method="$REPLACE_HOST_AUTH_WITH" '
/^[[:space:]]*#/ { print; next }
/^[[:space:]]*$/ { print; next }
{
if ($1 == "local" && $4 ~ /^(peer|ident)$/) {
$4 = local_method
} else if (($1 == "host" || $1 == "hostssl" || $1 == "hostnossl") && $5 ~ /^(peer|ident|md5|scram-sha-256|password|trust)$/) {
$5 = host_method
}
print
}
' "$hba_file" > "$tmp_file"
cat "$tmp_file" > "$hba_file"
rm -f "$tmp_file"
log "Перезапускаю ${SERVICE_NAME} после правки pg_hba.conf"
systemctl restart "$SERVICE_NAME"
wait_for_postgres
}
show_summary() {
local auth_mode_note
if [[ "$ENFORCE_PASSWORD_AUTH" == "true" ]]; then
auth_mode_note="да (${REPLACE_LOCAL_PEER_WITH} / ${REPLACE_HOST_AUTH_WITH})"
else
auth_mode_note="нет"
fi
cat <<EOF
Готово.
Что сделано:
- добавлен репозиторий PostgreSQL for 1C 18;
- установлен пакет в режиме: ${INSTALL_MODE};
- сервис: ${SERVICE_NAME};
- роль БД: ${PG_ADMIN_USER};
- суперпользователь: ${PG_ADMIN_SUPERUSER};
- база создана: ${PG_CREATE_DB}${PG_DB_NAME:+ (${PG_DB_NAME})};
- парольная аутентификация в pg_hba.conf: ${auth_mode_note}.
Проверки:
systemctl status ${SERVICE_NAME}
sudo -u postgres ${PSQL} -h ${POSTGRES_SOCKET_DIR} -d postgres -c "\du"
sudo -u postgres ${PSQL} -h ${POSTGRES_SOCKET_DIR} -d postgres -c "\l"
Подключение под новым пользователем:
${PSQL} -h 127.0.0.1 -U ${PG_ADMIN_USER} -d ${PG_DB_NAME:-postgres} -W
Если хотите использовать свой .env, просто скопируйте:
cp env.example .env
nano .env
sudo ./install_pg1c.sh
EOF
}
main() {
require_root
need_cmd systemctl
need_cmd runuser
need_cmd apt-get
need_cmd wget
need_cmd awk
need_cmd sed
load_env
check_os
ensure_base_packages
ensure_repo
install_pgpro
enable_and_start_service
wait_for_postgres
configure_role
configure_database
configure_pg_hba
show_summary
}
main "$@"