306 lines
9.0 KiB
Bash
Executable File
306 lines
9.0 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# =============================================================================
|
||
# SmartSolTech - Скрипт автоматического обновления
|
||
# =============================================================================
|
||
|
||
set -e # Выход при любой ошибке
|
||
|
||
# Цвета для вывода
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Функция для логирования
|
||
log() {
|
||
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||
}
|
||
|
||
success() {
|
||
echo -e "${GREEN}✅ $1${NC}"
|
||
}
|
||
|
||
warning() {
|
||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||
}
|
||
|
||
error() {
|
||
echo -e "${RED}❌ $1${NC}"
|
||
}
|
||
|
||
# Функция проверки зависимостей
|
||
check_dependencies() {
|
||
log "Проверка зависимостей..."
|
||
|
||
if ! command -v git &> /dev/null; then
|
||
error "Git не установлен"
|
||
exit 1
|
||
fi
|
||
|
||
if ! command -v docker &> /dev/null; then
|
||
error "Docker не установлен"
|
||
exit 1
|
||
fi
|
||
|
||
if ! command -v docker-compose &> /dev/null; then
|
||
error "Docker Compose не установлен"
|
||
exit 1
|
||
fi
|
||
|
||
success "Все зависимости найдены"
|
||
}
|
||
|
||
# Функция очистки staticfiles
|
||
cleanup_staticfiles() {
|
||
log "Очистка staticfiles..."
|
||
|
||
if [ -d "smartsoltech/staticfiles" ]; then
|
||
warning "Найдена папка staticfiles, удаляем..."
|
||
chmod -R 755 smartsoltech/staticfiles 2>/dev/null || true
|
||
rm -rf smartsoltech/staticfiles
|
||
success "Staticfiles очищены"
|
||
fi
|
||
}
|
||
|
||
# Функция обновления кода
|
||
update_code() {
|
||
log "Обновление кода из репозитория..."
|
||
|
||
# Сохраняем изменения если есть
|
||
if ! git diff --quiet; then
|
||
warning "Обнаружены локальные изменения, сохраняем..."
|
||
git stash push -m "Auto stash before update $(date)"
|
||
fi
|
||
|
||
# Получаем обновления
|
||
git fetch origin
|
||
|
||
# Обновляем текущую ветку
|
||
local current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||
git pull origin $current_branch
|
||
|
||
success "Код обновлен с ветки $current_branch"
|
||
}
|
||
|
||
# Функция остановки контейнеров
|
||
stop_containers() {
|
||
log "Остановка контейнеров..."
|
||
|
||
if docker-compose ps | grep -q "Up"; then
|
||
docker-compose down
|
||
success "Контейнеры остановлены"
|
||
else
|
||
warning "Контейнеры уже остановлены"
|
||
fi
|
||
}
|
||
|
||
# Функция сборки образов
|
||
build_images() {
|
||
log "Сборка Docker образов..."
|
||
|
||
# Принудительная пересборка
|
||
docker-compose build --no-cache
|
||
|
||
success "Образы собраны"
|
||
}
|
||
|
||
# Функция запуска контейнеров
|
||
start_containers() {
|
||
log "Запуск контейнеров..."
|
||
|
||
# Запуск в фоновом режиме
|
||
docker-compose up -d
|
||
|
||
# Ожидание готовности
|
||
log "Ожидание готовности сервисов..."
|
||
sleep 10
|
||
|
||
# Проверка статуса
|
||
if docker-compose ps | grep -q "Exit"; then
|
||
error "Некоторые контейнеры завершились с ошибкой"
|
||
docker-compose ps
|
||
return 1
|
||
fi
|
||
|
||
success "Контейнеры запущены"
|
||
}
|
||
|
||
# Функция выполнения миграций
|
||
run_migrations() {
|
||
log "Выполнение миграций Django..."
|
||
|
||
# Ожидание готовности БД
|
||
log "Ожидание готовности базы данных..."
|
||
sleep 15
|
||
|
||
# Выполнение миграций
|
||
docker-compose exec -T web python smartsoltech/manage.py migrate
|
||
|
||
success "Миграции выполнены"
|
||
}
|
||
|
||
# Функция сбора статических файлов
|
||
collect_static() {
|
||
log "Сбор статических файлов..."
|
||
|
||
docker-compose exec -T web python smartsoltech/manage.py collectstatic --noinput
|
||
|
||
success "Статические файлы собраны"
|
||
}
|
||
|
||
# Функция проверки состояния сервисов
|
||
health_check() {
|
||
log "Проверка состояния сервисов..."
|
||
|
||
# Проверка веб-сервера
|
||
local max_attempts=30
|
||
local attempt=1
|
||
|
||
while [ $attempt -le $max_attempts ]; do
|
||
if curl -sf http://localhost:8000/ > /dev/null 2>&1; then
|
||
success "Веб-сервер доступен"
|
||
break
|
||
fi
|
||
|
||
if [ $attempt -eq $max_attempts ]; then
|
||
error "Веб-сервер недоступен после $max_attempts попыток"
|
||
return 1
|
||
fi
|
||
|
||
log "Попытка $attempt/$max_attempts - ожидание веб-сервера..."
|
||
sleep 5
|
||
((attempt++))
|
||
done
|
||
|
||
# Показать статус контейнеров
|
||
echo ""
|
||
log "Статус контейнеров:"
|
||
docker-compose ps
|
||
|
||
success "Проверка здоровья завершена"
|
||
}
|
||
|
||
# Функция отображения логов
|
||
show_logs() {
|
||
log "Последние логи сервисов:"
|
||
echo ""
|
||
docker-compose logs --tail=20 web
|
||
}
|
||
|
||
# Функция бэкапа в удаленный репозиторий
|
||
backup_to_remote() {
|
||
log "Создание бэкапа в удаленном репозитории..."
|
||
|
||
if git remote | grep -q "backup"; then
|
||
# Проверяем есть ли изменения для коммита
|
||
if ! git diff --quiet || ! git diff --cached --quiet; then
|
||
git add .
|
||
git commit -m "Auto backup before update $(date '+%Y-%m-%d %H:%M:%S')"
|
||
fi
|
||
|
||
# Пушим в backup
|
||
git push backup master
|
||
success "Бэкап создан в удаленном репозитории"
|
||
else
|
||
warning "Backup репозиторий не настроен, пропускаем"
|
||
fi
|
||
}
|
||
|
||
# Главная функция
|
||
main() {
|
||
echo ""
|
||
echo "🚀 SmartSolTech - Автоматическое обновление"
|
||
echo "=========================================="
|
||
echo ""
|
||
|
||
# Проверка что мы в правильной директории
|
||
if [ ! -f "docker-compose.yml" ]; then
|
||
error "docker-compose.yml не найден. Запустите скрипт из корня проекта."
|
||
exit 1
|
||
fi
|
||
|
||
local start_time=$(date +%s)
|
||
|
||
# Выполняем все этапы
|
||
check_dependencies
|
||
backup_to_remote
|
||
cleanup_staticfiles
|
||
update_code
|
||
stop_containers
|
||
build_images
|
||
start_containers
|
||
run_migrations
|
||
collect_static
|
||
health_check
|
||
|
||
local end_time=$(date +%s)
|
||
local duration=$((end_time - start_time))
|
||
|
||
echo ""
|
||
echo "🎉 Обновление завершено успешно!"
|
||
echo "⏱️ Время выполнения: ${duration} секунд"
|
||
echo ""
|
||
echo "📊 Полезная информация:"
|
||
echo " • Веб-сайт: http://localhost:8000"
|
||
echo " • Админка: http://localhost:8000/admin"
|
||
echo " • PgAdmin: http://localhost:8080"
|
||
echo ""
|
||
|
||
# Предложение показать логи
|
||
read -p "Показать логи сервисов? (y/N): " show_logs_choice
|
||
if [[ $show_logs_choice =~ ^[Yy]$ ]]; then
|
||
show_logs
|
||
fi
|
||
|
||
success "Готово!"
|
||
}
|
||
|
||
# Обработка прерываний
|
||
trap 'echo ""; error "Обновление прервано пользователем"; exit 130' INT TERM
|
||
|
||
# Обработка ошибок
|
||
error_handler() {
|
||
local line_no=$1
|
||
error "Ошибка на строке $line_no"
|
||
echo ""
|
||
echo "Для диагностики можете выполнить:"
|
||
echo " docker-compose logs"
|
||
echo " docker-compose ps"
|
||
exit 1
|
||
}
|
||
|
||
trap 'error_handler $LINENO' ERR
|
||
|
||
# Запуск с параметрами
|
||
case "${1:-}" in
|
||
--help|-h)
|
||
echo "SmartSolTech - Скрипт автоматического обновления"
|
||
echo ""
|
||
echo "Использование:"
|
||
echo " $0 - Полное обновление (по умолчанию)"
|
||
echo " $0 --help - Показать эту справку"
|
||
echo " $0 --logs - Показать логи без обновления"
|
||
echo " $0 --status - Показать статус без обновления"
|
||
echo ""
|
||
exit 0
|
||
;;
|
||
--logs)
|
||
show_logs
|
||
exit 0
|
||
;;
|
||
--status)
|
||
docker-compose ps
|
||
health_check
|
||
exit 0
|
||
;;
|
||
"")
|
||
main
|
||
;;
|
||
*)
|
||
error "Неизвестный параметр: $1"
|
||
echo "Используйте --help для справки"
|
||
exit 1
|
||
;;
|
||
esac |