Содержание
Хранилище файлов NFS, без встроенного почтового сервера
Краткое описание
Скрипты основаны на инструкциях по установке Корпоративный сервер 2024 в архитектуре middle
Для работы скриптов необходимо наличие установленного rsync на серверах участвующих в схеме КС и с которого запускается скрипт. На сервере, с которого запускается скрипт, необходимо установить lbzip2 (в скрипте есть проверка).
Скрипт копирует и архивирует информацию из папок
Сервер с ролью Диск
/etc/supervisor (в REDOS /etc/supervisor.d)/opt/r7-office/var/r7-office/var/www/r7-office
Сервер с ролью Сервер документов
/etc/r7-office/var/www/r7-office
Сервер с ролью Поиск
/opt/r7-office/var/r7-office/etc/supervisor (в REDOS /etc/supervisor.d)
Сервер с ролью NFS
/mnt/nfs
Перед запуском необходимо вписать следующую информацию
- Если для доступа к серверам используется достпуп по ключу, вписать путь.
- Если доступ без ключа, тогда нужно изменить команды доступа у rsync и ssh.
- Если для доступа по ssh используется нестандартный порт, так же нужно указать в командах.
- Нужно ввести адреса серверов согласно их ролям.
Описание переменных
| Переменная | Описание |
| BACKUP_DIR= | Папка для хранения архивов |
| BACKUP_DATE=$(date + ‘%Y-%m-%d’) | Формат даты для имени архива |
| SSH_KEY_PATH= | Путь к SSH ключу |
| SSH_PORT=22 | SSH порт по которму осуществляется подключение к серверам |
| NUM_CORES=$(($(nproc)/2)) | Для работы архиватора по-умолчанию берется половина ядер на сервере бэкапа |
| DS_IP=172.16.10.11 | Адрес сервера с ролью Сервер документов |
| KS_IP=172.16.10.12 | Адрес сервера с ролью Диск |
| SRCH_IP=172.16.10.13 | Адрес сервера с ролью Поиск |
| NFS_IP=172.16.10.14 | Адрес сервера с ролью NFS |
| BACKUP_FILE | Имя файла с архивом для восстановления |
Список переменных с адресами серверов вынесен в отдельный файл backup.conf
#BACKUP_FILE="cddisk-2024-04-23.tar.bz2" #Только для восстановления данных из архива
BACKUP_DIR="backup/corpportal"
BACKUP_DATE=$(date +'%Y-%m-%d')
SSH_KEY_PATH="backup/id_rsa"
SSH_PORT=22
NUM_CORES=$(( ($(nproc) + 1) / 2 ))
DS_IP="172.16.10.11"
KS_IP="172.16.10.12"
SRCH_IP="172.16.10.13"
NFS_IP="172.16.10.14"
LOG_FILE="$BACKUP_DIR/backup_${BACKUP_DATE}.log" #Имя файла содержит датуПример скрипта для создания резервной копии
#!/bin/bash
# Путь до файла конфигурации
source backup.conf
# Вызов функции cleanup после выполнения прерывания
trap cleanup INT TERM
trap cleanup_exit EXIT
# Одновременный вывод в консоль и в лог файл
#exec > >(tee -a "$LOG_FILE") 2>&1
cleanup() {
log_info "Завершение скрипта после прерывания..."
# Добавить что то если нужно
exit 1
}
cleanup_exit() {
log_info "Завершение скрипта..."
# Добавить что то если нужно
exit 1
}
# Функции логирования
log_info() {
echo "$(date +'%Y-%m-%d %H:%M:%S') INFO: $1" | tee -a "$LOG_FILE"
}
log_warn() {
echo "$(date +'%Y-%m-%d %H:%M:%S') WARN: $1" | tee -a "$LOG_FILE"
}
log_error() {
echo "$(date +'%Y-%m-%d %H:%M:%S') ERROR: $1" | tee -a "$LOG_FILE"
}
# Создаем backup каталог
mkdir -p "$BACKUP_DIR"
# Проверка, установлен ли lbzip2 и rsync
if ! command -v lbzip2 &> /dev/null; then
log_error "Ошибка: lbzip2 не установлен. Установите lbzip2 и повторите попытку."
exit 1
fi
if ! command -v rsync &> /dev/null; then
log_error "Ошибка: rsync не установлен. Установите rsync и повторите попытку."
exit 1
fi
# Функция для получения пути до директории supervisor
get_supervisor_dir() {
local server=$1
local supervisor_dir=""
# Проверяем наличие каталогов в порядке приоритета
if ssh -i "$SSH_KEY_PATH" -p "$SSH_PORT" root@"$server" "test -d /etc/supervisord.d" 2>/dev/null; then
supervisor_dir="/etc/supervisord.d"
elif ssh -i "$SSH_KEY_PATH" -p "$SSH_PORT" root@"$server" "test -d /etc/supervisor" 2>/dev/null; then
supervisor_dir="/etc/supervisor"
else
log_error "Не найден каталог supervisor на сервере $server"
return 1
fi
#log_info "На сервере $server путь до supervisor $supervisor_dir"
echo $supervisor_dir
return 0
}
get_databases(){
scp -i "$SSH_KEY_PATH" -P "$SSH_PORT" root@"$KS_IP":/opt/r7-office/Api/appsettings.json .
# Проверка кода выхода
SCP_EXIT_STATUS=$?
# Обработка результата
if [ $SCP_EXIT_STATUS -eq 0 ]; then
log_info "Файл конфигурации удалось скопировать"
else
log_error "Файл конфигурации не удалось скопировать"
exit 1 # Завершаем скрипт с ошибкой
fi
# Данные для авторизации в PostgreSQL
DB_PATH_PARAM=./appsettings.json
PSQL_HOST=$(grep -oP "Host=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2);
PSQL_DB_NAME=$(grep -oP "Database=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2);
PSQL_USER=$(grep -oP "Username=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2);
PSQL_PASS=$(grep -oP "Password=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2);
PSQL_PORT=$(grep -oP "Port=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2);
export PGPASSWORD=$PSQL_PASS
PSQL="psql -b -h$PSQL_HOST -p$PSQL_PORT -d$PSQL_DB_NAME -U$PSQL_USER"
echo "DB_HOST=$PSQL_HOST"
echo "DB_PORT=$PSQL_PORT"
echo "DB_NAME=$PSQL_DB_NAME"
echo "DB_USER=$PSQL_USER"
echo "PSQL=$PSQL"
# Удалить файл конфигурации
rm -rf $DB_PATH_PARAM
# Очистка от старых дампов
rm -rf $BACKUP_DIR/cddisk_db_*.tar.gz
local db_backup_file="$BACKUP_DIR/cddisk_db_$BACKUP_DATE.tar.gz"
pg_dump -v -h $PSQL_HOST -U $PSQL_USER -d $PSQL_DB_NAME -F c -c -f "$db_backup_file"
if [ $? -eq 0 ]; then
log_info "Бэкап успешно создан"
else
log_error "Бэкап создан с ошибкой"
exit 1 # Завершаем скрипт с ошибкой
fi
}
# Время начала создания бэкапа
START_BACKUP_TIME=$(date +'%Y-%m-%d %H:%M:%S')
log_info "Начало резервного копирования: $START_BACKUP_TIME"
# Получить каталоги supervisor
KS_SUPERVISOR_DIR=$(get_supervisor_dir $KS_IP)
SRCH_SUPERVISOR_DIR=$(get_supervisor_dir $SRCH_IP)
mkdir -p $BACKUP_DIR/ds/etc/r7-office
mkdir -p $BACKUP_DIR/ds/var/www/r7-office
mkdir -p $BACKUP_DIR/ks/$KS_SUPERVISOR_DIR
mkdir -p $BACKUP_DIR/ks/opt/r7-office
mkdir -p $BACKUP_DIR/ks/var/r7-office
mkdir -p $BACKUP_DIR/ks/var/www/r7-office
mkdir -p $BACKUP_DIR/srch/opt/r7-office
mkdir -p $BACKUP_DIR/srch/$SRCH_SUPERVISOR_DIR
mkdir -p $BACKUP_DIR/srch/var/r7-office
mkdir -p $BACKUP_DIR/nfs/mnt/
rsync_msg(){
code_err=$1
host_ip=$2
# Проверяем код возврата
if [ $code_err -eq 23 ]; then
log_error "Ошибка: rsync не установлен или произошла другая фатальная ошибка на удаленном хосте $host_ip. (code 23). Проверьте установку rsync или настройки сети."
exit 1
elif [ $code_err -ne 0 ]; then
log_error "Ошибка rsync (code $code_err) при копировании с $host_ip. Смотрите лог: $LOG_FILE"
exit 1
fi
log_info "Копирование с $host_ip завершено успешно."
}
# Получить дамп базы
get_databases
# RSYNC копирование данных с удаленный серверов
log_info "Начало копирования с сервера $DS_IP из каталога /etc/r7-office"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$DS_IP:/etc/r7-office $BACKUP_DIR/ds/etc/r7-office/
rsync_msg $? $DS_IP
log_info "Начало копирования с сервера $DS_IP из каталога /var/www/r7-office"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$DS_IP:/var/www/r7-office $BACKUP_DIR/ds/var/www/r7-office/
rsync_msg $? $DS_IP
log_info "Начало копирования с сервера $KS_IP из каталога $KS_SUPERVISOR_DIR"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$KS_IP:$KS_SUPERVISOR_DIR $BACKUP_DIR/ks/$KS_SUPERVISOR_DIR/
rsync_msg $? $KS_IP
log_info "Начало копирования с сервера $KS_IP из каталога /opt/r7-office"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$KS_IP:/opt/r7-office $BACKUP_DIR/ks/opt/r7-office/
rsync_msg $? $KS_IP
log_info "Начало копирования с сервера $KS_IP из каталога /var/r7-office"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$KS_IP:/var/r7-office $BACKUP_DIR/ks/var/r7-office/
rsync_msg $? $KS_IP
log_info "Начало копирования с сервера $KS_IP из каталога /var/www/r7-office"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$KS_IP:/var/www/r7-office $BACKUP_DIR/ks/var/www/r7-office/
rsync_msg $? $KS_IP
log_info "Начало копирования с сервера $SRCH_IP из каталога /opt/r7-office"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$SRCH_IP:/opt/r7-office $BACKUP_DIR/srch/opt/r7-office/
rsync_msg $? $SRCH_IP
log_info "Начало копирования с сервера $SRCH_IP из каталога $SRCH_SUPERVISOR_DIR"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$SRCH_IP:$SRCH_SUPERVISOR_DIR $BACKUP_DIR/srch/$SRCH_SUPERVISOR_DIR/
rsync_msg $? $SRCH_IP
log_info "Начало копирования с сервера $SRCH_IP из каталога /var/r7-office"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$SRCH_IP:/var/r7-office $BACKUP_DIR/srch/var/r7-office/
rsync_msg $? $SRCH_IP
log_info "Начало копирования с сервера $NFS_IP из каталога /mnt/nfs"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" root@$NFS_IP:/mnt/ $BACKUP_DIR/nfs/mnt/
rsync_msg $? $NFS_IP
# Создание архива с бэкапом
BACKUP_DATE=$(date +'%Y-%m-%d %H:%M:%S')
log_info "Формируется архив..."
tar cvf "$BACKUP_DIR/cddisk-${BACKUP_DATE}.tar.bz2" --selinux --use-compress-prog="lbzip2 -k -n$NUM_CORES" $BACKUP_DIR/ds/etc/r7-office $BACKUP_DIR/ds/var/www/r7-office $BACKUP_DIR/ks/$KS_SUPERVISOR_DIR $BACKUP_DIR/ks/opt/r7-office $BACKUP_DIR/ks/var/r7-office $BACKUP_DIR/ks/var/www/r7-office $BACKUP_DIR/srch/opt/r7-office $BACKUP_DIR/srch/$SRCH_SUPERVISOR_DIR $BACKUP_DIR/srch/var/r7-office $BACKUP_DIR/nfs/mnt/nfs $db_backup_file
if [ $? -eq 0 ]; then
log_info "Архив успешно создан"
else
log_error "Архив создан с ошибкой"
exit 1 # Завершаем скрипт с ошибкой
fi
# Время завершения бекапирования
END_BACKUP_TIME=$(date +'%Y-%m-%d %H:%M:%S')
log_info "Завершение резервного копирования: $end_time"
# Время в секундах работы бекапирования
START_TIMESTAMP=$(date -d "$START_BACKUP_TIME" +%s)
END_TIMESTAMP=$(date -d "$END_BACKUP_TIME" +%s)
TOTAL_DURATION=$((END_TIMESTAMP - START_TIMESTAMP))
log_info "Общее время выполнения: $TOTAL_DURATION секунд"
log_info "Завершение резервного копирования: $(date +'%Y-%m-%d %H:%M:%S')"Восстановление из архива
Обратите внимание, если при восстановлении изменились адреса серверов внутри архитектуры, возможны ошибки в работе Корпоративного сервера. Нужно будет проверить все настройки, связанные с этими серверами согласно инструкции по установке.
Пример скрипта восстановления
#!/bin/bash
# Путь до файла конфигурации
source restore.conf
# Функция для обработки прерываний
trap cleanup INT TERM
trap cleanup_exit EXIT
# Функции для логирования
log_info() {
echo "$(date +'%Y-%m-%d %H:%M:%S') INFO: \$1" | tee -a "$LOG_FILE"
}
log_warn() {
echo "$(date +'%Y-%m-%d %H:%M:%S') WARN: \$1" | tee -a "$LOG_FILE"
}
log_error() {
echo "$(date +'%Y-%m-%d %H:%M:%S') ERROR: \$1" | tee -a "$LOG_FILE"
}
# Функция очистки при прерывании
cleanup() {
log_info "Скрипт восстановления прерван. Выполняется очистка..."
# Добавьте дополнительные шаги очистки, если необходимо
exit 1
}
# Функция очистки при выходе
cleanup_exit() {
log_info "Скрипт восстановления завершает работу."
# Добавьте дополнительные шаги очистки, если необходимо
exit 1
}
# Проверка наличия необходимых команд
if ! command -v lbzip2 &> /dev/null; then
log_error "Ошибка: lbzip2 не установлен. Установите lbzip2 и повторите попытку."
exit 1
fi
if ! command -v rsync &> /dev/null; then
log_error "Ошибка: rsync не установлен. Установите rsync и повторите попытку."
exit 1
fi
if ! command -v psql &> /dev/null; then
log_error "Ошибка: psql не установлен. Установите psql и повторите попытку."
exit 1
fi
# Функция для получения пути до директории supervisor
get_supervisor_dir() {
local server=\$1
local supervisor_dir=""
if ssh -i "$SSH_KEY_PATH" -p "$SSH_PORT" root@"$server" "test -d /etc/supervisord.d" 2>/dev/null; then
supervisor_dir="/etc/supervisord.d"
elif ssh -i "$SSH_KEY_PATH" -p "$SSH_PORT" root@"$server" "test -d /etc/supervisor" 2>/dev/null; then
supervisor_dir="/etc/supervisor"
else
log_error "Не найден каталог supervisor на сервере $server"
return 1
fi
echo "$supervisor_dir"
return 0
}
# Функция для восстановления баз данных
restore_databases() {
# Копируем файл конфигурации appsettings.json из резервной копии
scp -i "$SSH_KEY_PATH" -P "$SSH_PORT" root@"$KS_IP":"$BACKUP_DIR/ks/opt/r7-office/appsettings.json" .
SCP_EXIT_STATUS=$?
if [ $SCP_EXIT_STATUS -eq 0 ]; then
log_info "Файл конфигурации успешно скопирован."
else
log_error "Не удалось скопировать файл конфигурации."
exit 1
fi
# Извлекаем параметры для подключения к PostgreSQL
DB_PATH_PARAM=./appsettings.json
PSQL_HOST=$(grep -oP "Host=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2)
PSQL_DB_NAME=$(grep -oP "Database=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2)
PSQL_USER=$(grep -oP "Username=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2)
PSQL_PASS=$(grep -oP "Password=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2)
PSQL_PORT=$(grep -oP "Port=[^\";]*" $DB_PATH_PARAM | head -1 | cut -d'=' -f2)
export PGPASSWORD=$PSQL_PASS
PSQL="psql -h $PSQL_HOST -p $PSQL_PORT -U $PSQL_USER -d postgres"
# Проверяем существование базы данных
DATABASE_EXISTS=$($PSQL -tc "SELECT 1 FROM pg_database WHERE datname = '$PSQL_DB_NAME';")
if [ -z "$DATABASE_EXISTS" ]; then
# База данных не существует, создаем её
log_info "База данных $PSQL_DB_NAME не существует. Создание новой базы данных."
$PSQL -c "CREATE DATABASE $PSQL_DB_NAME;"
if [ $? -eq 0 ]; then
log_info "База данных $PSQL_DB_NAME успешно создана."
else
log_error "Не удалось создать базу данных $PSQL_DB_NAME."
exit 1
fi
else
# База данных существует, удаляем её перед восстановлением
log_info "База данных $PSQL_DB_NAME существует. Удаление существующей базы данных."
$PSQL -c "DROP DATABASE IF EXISTS $PSQL_DB_NAME;"
if [ $? -eq 0 ]; then
log_info "Существующая база данных $PSQL_DB_NAME успешно удалена."
else
log_error "Не удалось удалить существующую базу данных $PSQL_DB_NAME."
exit 1
fi
# Создаем новую базу данных
$PSQL -c "CREATE DATABASE $PSQL_DB_NAME;"
if [ $? -eq 0 ]; then
log_info "Новая база данных $PSQL_DB_NAME успешно создана."
else
log_error "Не удалось создать новую базу данных $PSQL_DB_NAME."
exit 1
fi
fi
# Восстанавливаем базу данных из резервной копии
pg_restore -h $PSQL_HOST -p $PSQL_PORT -U $PSQL_USER -d $PSQL_DB_NAME -v "$BACKUP_DIR/cddisk_db_$BACKUP_DATE.tar.gz"
if [ $? -eq 0 ]; then
log_info "База данных $PSQL_DB_NAME успешно восстановлена."
else
log_error "Не удалось восстановить базу данных $PSQL_DB_NAME."
exit 1
fi
# Удаляем файл конфигурации
rm -f $DB_PATH_PARAM
}
# Начало процесса восстановления
START_RESTORE_TIME=$(date +'%Y-%m-%d %H:%M:%S')
log_info "Начало процесса восстановления: $START_RESTORE_TIME"
# Восстановление баз данных
restore_databases
# Восстановление данных с помощью rsync
log_info "Начало восстановления данных с резервной копии на серверы."
# Восстановление данных на сервер DS
log_info "Восстановление /etc/r7-office на $DS_IP"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/ds/etc/r7-office/ root@$DS_IP:/etc/r7-office/
rsync_msg $? $DS_IP
log_info "Восстановление /var/www/r7-office на $DS_IP"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/ds/var/www/r7-office/ root@$DS_IP:/var/www/r7-office/
rsync_msg $? $DS_IP
# Восстановление данных на сервер KS
log_info "Восстановление директории supervisor на $KS_IP"
KS_SUPERVISOR_DIR=$(get_supervisor_dir $KS_IP)
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/ks/$KS_SUPERVISOR_DIR/ root@$KS_IP:$KS_SUPERVISOR_DIR/
rsync_msg $? $KS_IP
log_info "Восстановление /opt/r7-office на $KS_IP"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/ks/opt/r7-office/ root@$KS_IP:/opt/r7-office/
rsync_msg $? $KS_IP
log_info "Восстановление /var/r7-office на $KS_IP"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/ks/var/r7-office/ root@$KS_IP:/var/r7-office/
rsync_msg $? $KS_IP
log_info "Восстановление /var/www/r7-office на $KS_IP"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/ks/var/www/r7-office/ root@$KS_IP:/var/www/r7-office/
rsync_msg $? $KS_IP
# Восстановление данных на сервер SRCH
log_info "Восстановление директории supervisor на $SRCH_IP"
SRCH_SUPERVISOR_DIR=$(get_supervisor_dir $SRCH_IP)
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/srch/$SRCH_SUPERVISOR_DIR/ root@$SRCH_IP:$SRCH_SUPERVISOR_DIR/
rsync_msg $? $SRCH_IP
log_info "Восстановление /opt/r7-office на $SRCH_IP"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/srch/opt/r7-office/ root@$SRCH_IP:/opt/r7-office/
rsync_msg $? $SRCH_IP
log_info "Восстановление /var/r7-office на $SRCH_IP"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/srch/var/r7-office/ root@$SRCH_IP:/var/r7-office/
rsync_msg $? $SRCH_IP
# Восстановление данных NFS
log_info "Восстановление данных NFS на $NFS_IP"
rsync -avz --partial -e "ssh -i $SSH_KEY_PATH -p $SSH_PORT" --log-file="$LOG_FILE" $BACKUP_DIR/nfs/mnt/ root@$NFS_IP:/mnt/
rsync_msg $? $NFS_IP
# Завершение процесса восстановления
END_RESTORE_TIME=$(date +'%Y-%m-%d %H:%M:%S')
log_info "Процесс восстановления завершен: $END_RESTORE_TIME"
# Рассчитываем общее время выполнения
START_TIMESTAMP=$(date -d "$START_RESTORE_TIME" +%s)
END_TIMESTAMP=$(date -d "$END_RESTORE_TIME" +%s)
TOTAL_DURATION=$((END_TIMESTAMP - START_TIMESTAMP))
log_info "Общее время выполнения: $TOTAL_DURATION секунд"
