Продукты Р7
Корпоративный сервер 2024
Корпоративный сервер 2024
Сервер документов
Сервер документов
Редакторы
Редакторы
Корпоративный сервер 2019
Корпоративный сервер 2019
Графика
Графика
Команда
Команда
Мобильные редакторы
Мобильные редакторы
Облачный офис
Облачный офис
Почта
Почта
Органайзер
Органайзер
Дополнительно
Часто задаваемые вопросы
Разработчикам
Интеграции
Новые возможности

Резервное копирование/восстановление Корпоративный сервер 2024 архитектура Middle

Обновлено: 25.12.25

Хранилище файлов 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

Перед запуском необходимо вписать следующую информацию

  1. Если для доступа к серверам используется достпуп по ключу, вписать путь.
  2. Если доступ без ключа, тогда нужно изменить команды доступа у rsync и ssh.
  3. Если для доступа по ssh используется нестандартный порт, так же нужно указать в командах.
  4. Нужно ввести адреса серверов согласно их ролям.

Описание переменных

Переменная Описание
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 секунд"