#!/bin/bash # Скрипт post-deploy.sh для автоматического развертывания проекта # Выполняется после развертывания проекта set -e # Остановка при любой ошибке # Цвета для вывода RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Функция для записи в лог-файл write_to_log() { local message="$1" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo "[$timestamp] [PostDeploy] $message" >> "$LOG_FILE" } # Функция для логирования log() { local message="$1" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo -e "${GREEN}[$timestamp] $1${NC}" write_to_log "$message" } error() { local message="$1" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo -e "${RED}[$timestamp] ERROR: $1${NC}" write_to_log "ERROR: $message" exit 1 } warning() { local message="$1" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo -e "${YELLOW}[$timestamp] WARNING: $1${NC}" write_to_log "WARNING: $message" } # Определяем корневую директорию проекта PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" VENV_DIR="$PROJECT_ROOT/venv" REQUIREMENTS_FILE="$PROJECT_ROOT/requirements.txt" BACKUP_SCRIPT="$PROJECT_ROOT/backupdb.sh" ENSURE_DB_SCRIPT="$PROJECT_ROOT/ensure_db.py" SERVICES_DIR="$PROJECT_ROOT/services" SERVICES_BACKUP_DIR="$SERVICES_DIR/backups" SYSTEMD_DIR="/etc/systemd/system" # Загружаем переменные окружения из .env файла if [ -f "$PROJECT_ROOT/.env" ]; then # Безопасная загрузка переменных из .env файла while IFS= read -r line || [ -n "$line" ]; do # Пропускаем пустые строки и комментарии if [[ -n "$line" && ! "$line" =~ ^[[:space:]]*# ]]; then # Проверяем, что строка содержит знак равенства if [[ "$line" =~ ^[^=]+=.* ]]; then # Экспортируем переменную export "$line" fi fi done < "$PROJECT_ROOT/.env" fi # Определяем лог-файл из переменной окружения или используем значение по умолчанию LOG_FILE="${LOG_FILE:-$PROJECT_ROOT/post-deploy.log}" # Выводим информацию о лог-файле (только в консоль, чтобы не создавать циклическое логирование) echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] Лог-файл: $LOG_FILE${NC}" log "Начинаем post-deploy процесс для проекта: $PROJECT_ROOT" # 0. Установка прав на исполнение для всех .sh файлов в основном каталоге проекта log "Устанавливаем права на исполнение для всех .sh файлов в проекте..." # Находим все .sh файлы в основном каталоге проекта (не в подкаталогах) for sh_file in "$PROJECT_ROOT"/*.sh; do if [ -f "$sh_file" ]; then chmod +x "$sh_file" log "Установлены права на исполнение для: $(basename "$sh_file")" fi done # 1. Проверка и создание виртуального окружения Python log "Проверяем наличие виртуального окружения Python..." if [ ! -d "$VENV_DIR" ]; then log "Виртуальное окружение не найдено. Создаем новое..." # Проверяем наличие python3 if ! command -v python3 &> /dev/null; then error "Python3 не найден в системе. Установите Python3 перед продолжением." fi # Создаем виртуальное окружение python3 -m venv "$VENV_DIR" if [ $? -eq 0 ]; then log "Виртуальное окружение успешно создано" else error "Ошибка при создании виртуального окружения" fi else log "Виртуальное окружение уже существует" fi # Активируем виртуальное окружение log "Активируем виртуальное окружение..." source "$VENV_DIR/bin/activate" # Проверяем наличие requirements.txt if [ ! -f "$REQUIREMENTS_FILE" ]; then error "Файл requirements.txt не найден в $REQUIREMENTS_FILE" fi # Обновляем pip и устанавливаем зависимости log "Обновляем pip и устанавливаем зависимости из requirements.txt..." pip install --upgrade pip pip install -r "$REQUIREMENTS_FILE" if [ $? -eq 0 ]; then log "Зависимости успешно установлены" else error "Ошибка при установке зависимостей" fi # 2. Запуск backupdb.sh для бэкапа базы данных log "Запускаем бэкап базы данных..." if [ ! -f "$BACKUP_SCRIPT" ]; then error "Скрипт backupdb.sh не найден в $BACKUP_SCRIPT" fi # Делаем скрипт исполняемым chmod +x "$BACKUP_SCRIPT" # Запускаем бэкап bash "$BACKUP_SCRIPT" if [ $? -eq 0 ]; then log "Бэкап базы данных выполнен успешно" else error "Ошибка при выполнении бэкапа базы данных" fi # 3. Запуск ensure_db.py для проверки и создания БД log "Запускаем проверку и создание структуры базы данных..." if [ ! -f "$ENSURE_DB_SCRIPT" ]; then error "Скрипт ensure_db.py не найден в $ENSURE_DB_SCRIPT" fi # Запускаем скрипт проверки БД python3 "$ENSURE_DB_SCRIPT" if [ $? -eq 0 ]; then log "Проверка и создание структуры базы данных выполнена успешно" else error "Ошибка при выполнении проверки базы данных" fi # 4. Проверка и обновление systemd сервисов log "Проверяем и обновляем systemd сервисы..." # Создаем каталог для резервных копий сервисов mkdir -p "$SERVICES_BACKUP_DIR" # Список сервисов для проверки SERVICES=("testbot-git.service" "testedit-git.service") for service in "${SERVICES[@]}"; do log "Обрабатываем сервис: $service" SERVICE_FILE="$SERVICES_DIR/$service" SYSTEMD_SERVICE="$SYSTEMD_DIR/$service" # Проверяем наличие файла сервиса в проекте if [ ! -f "$SERVICE_FILE" ]; then warning "Файл сервиса $SERVICE_FILE не найден, пропускаем" continue fi # Проверяем, нужно ли обновлять сервис UPDATE_NEEDED=false if [ ! -f "$SYSTEMD_SERVICE" ]; then log "Сервис $service не найден в systemd, будет создан" UPDATE_NEEDED=true else # Сравниваем даты модификации файлов if [ "$SERVICE_FILE" -nt "$SYSTEMD_SERVICE" ]; then log "Файл сервиса $service в проекте новее, обновляем" UPDATE_NEEDED=true else log "Сервис $service актуален, пропускаем" fi fi if [ "$UPDATE_NEEDED" = true ]; then log "Копируем файл сервиса $service в systemd..." # Создаем резервную копию существующего файла в каталог проекта if [ -f "$SYSTEMD_SERVICE" ]; then BACKUP_FILE="$SERVICES_BACKUP_DIR/${service}.backup.$(date +%Y%m%d_%H%M%S)" sudo cp "$SYSTEMD_SERVICE" "$BACKUP_FILE" log "Создана резервная копия: $BACKUP_FILE" fi # Копируем новый файл сервиса sudo cp "$SERVICE_FILE" "$SYSTEMD_SERVICE" if [ $? -eq 0 ]; then log "Файл сервиса $service успешно скопирован" else error "Ошибка при копировании файла сервиса $service" fi # Устанавливаем правильные права доступа sudo chmod 644 "$SYSTEMD_SERVICE" sudo chown root:root "$SYSTEMD_SERVICE" fi done # 5. Перезапуск сервисов log "Перезапускаем systemd сервисы..." for service in "${SERVICES[@]}"; do SYSTEMD_SERVICE="$SYSTEMD_DIR/$service" if [ -f "$SYSTEMD_SERVICE" ]; then log "Останавливаем сервис $service..." sudo systemctl stop "$service" || warning "Не удалось остановить сервис $service (возможно, не запущен)" log "Перезагружаем конфигурацию systemd..." sudo systemctl daemon-reload log "Запускаем сервис $service..." sudo systemctl start "$service" if [ $? -eq 0 ]; then log "Сервис $service успешно запущен" # Проверяем статус сервиса sleep 2 if sudo systemctl is-active --quiet "$service"; then log "Сервис $service активен и работает" else warning "Сервис $service запущен, но может работать некорректно" sudo systemctl status "$service" --no-pager -l fi else error "Ошибка при запуске сервиса $service" fi # Включаем автозапуск сервиса sudo systemctl enable "$service" log "Автозапуск для сервиса $service включен" else warning "Файл сервиса $SYSTEMD_SERVICE не найден, пропускаем перезапуск" fi done log "Post-deploy процесс завершен успешно!" log "Все сервисы обновлены и перезапущены" # Показываем статус всех сервисов log "Текущий статус сервисов:" for service in "${SERVICES[@]}"; do if sudo systemctl list-unit-files | grep -q "$service"; then echo -n " $service: " if sudo systemctl is-active --quiet "$service"; then echo -e "${GREEN}АКТИВЕН${NC}" else echo -e "${RED}НЕАКТИВЕН${NC}" fi else echo -e " $service: ${YELLOW}НЕ НАЙДЕН${NC}" fi done