🔧 Restructure scripts and add CLI tool
✨ New features: - Add CLI tool for container command execution - Reorganize all scripts into bin/ directory - Create convenient wrappers in project root - Add local changes auto-commit functionality - Enhanced backup repository management 📁 Structure changes: - Move all scripts to bin/ directory - Create wrapper scripts in root (cli, update, start, stop, logs) - Add setup-backup.sh for backup repository management - Update documentation with new CLI examples 🛠️ CLI capabilities: - Django commands (shell, migrate, collectstatic, etc.) - System commands (bash, logs, status) - Container management (restart, status) - Interactive and non-interactive modes 📚 Documentation: - Updated SCRIPTS_README.md with CLI examples - Added troubleshooting section - Comprehensive usage examples
This commit is contained in:
370
bin/update.sh
Executable file
370
bin/update.sh
Executable file
@@ -0,0 +1,370 @@
|
||||
#!/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
|
||||
}
|
||||
|
||||
# Функция сохранения локальных изменений
|
||||
save_local_changes() {
|
||||
log "Проверка локальных изменений..."
|
||||
|
||||
# Проверяем есть ли изменения в рабочей директории или индексе
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
warning "Обнаружены локальные изменения, сохраняем в коммит..."
|
||||
|
||||
# Добавляем все изменения
|
||||
git add .
|
||||
|
||||
# Создаем коммит с временной меткой
|
||||
local commit_msg="Auto commit before update $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
if git commit -m "$commit_msg"; then
|
||||
success "Локальные изменения сохранены в коммит"
|
||||
log "Коммит: $commit_msg"
|
||||
else
|
||||
warning "Не удалось создать коммит (возможно нет изменений для коммита)"
|
||||
fi
|
||||
else
|
||||
log "Локальных изменений не обнаружено"
|
||||
fi
|
||||
}
|
||||
update_code() {
|
||||
local remote_name="${1:-origin}"
|
||||
log "Обновление кода из репозитория $remote_name..."
|
||||
|
||||
# Проверяем существование удаленного репозитория
|
||||
if ! git remote | grep -q "^${remote_name}$"; then
|
||||
error "Удаленный репозиторий '$remote_name' не найден"
|
||||
log "Доступные репозитории:"
|
||||
git remote -v
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Настраиваем стратегию pull если не настроено
|
||||
if [ -z "$(git config pull.rebase 2>/dev/null)" ]; then
|
||||
log "Настраиваем стратегию Git pull..."
|
||||
git config pull.rebase false
|
||||
fi
|
||||
|
||||
# Получаем обновления
|
||||
log "Получение обновлений из $remote_name..."
|
||||
git fetch $remote_name
|
||||
|
||||
# Обновляем текущую ветку
|
||||
local current_branch
|
||||
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
# Пробуем обновить с обработкой конфликтов
|
||||
if ! git pull $remote_name $current_branch; then
|
||||
error "Не удалось обновить код. Возможно есть конфликты."
|
||||
log "Попробуйте выполнить команды вручную:"
|
||||
log " git status"
|
||||
log " git merge --abort # если нужно отменить"
|
||||
log " git pull $remote_name $current_branch"
|
||||
return 1
|
||||
fi
|
||||
|
||||
success "Код обновлен с ветки $current_branch из $remote_name"
|
||||
}
|
||||
|
||||
# Функция остановки контейнеров
|
||||
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() {
|
||||
local backup_remote="${1:-backup}"
|
||||
|
||||
# Пропускаем если это тот же репозиторий что используется для обновления
|
||||
local update_remote="${2:-origin}"
|
||||
if [ "$backup_remote" = "$update_remote" ]; then
|
||||
log "Пропускаем бэкап - используется тот же репозиторий для обновления"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Создание бэкапа в удаленном репозитории $backup_remote..."
|
||||
|
||||
if git remote | grep -q "^${backup_remote}$"; then
|
||||
# Пушим текущее состояние в backup (изменения уже сохранены в коммит)
|
||||
if git push $backup_remote master; then
|
||||
success "Бэкап создан в удаленном репозитории $backup_remote"
|
||||
else
|
||||
warning "Не удалось создать бэкап в $backup_remote"
|
||||
fi
|
||||
else
|
||||
warning "$backup_remote репозиторий не настроен, пропускаем бэкап"
|
||||
fi
|
||||
}
|
||||
|
||||
# Главная функция
|
||||
main() {
|
||||
local remote_source="${1:-origin}"
|
||||
local backup_remote="${2:-backup}"
|
||||
|
||||
echo ""
|
||||
echo "🚀 SmartSolTech - Автоматическое обновление"
|
||||
echo "=========================================="
|
||||
echo "📡 Источник: $remote_source"
|
||||
if git remote | grep -q "^${backup_remote}$"; then
|
||||
echo "💾 Бэкап: $backup_remote"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Проверка что мы в правильной директории
|
||||
if [ ! -f "docker-compose.yml" ]; then
|
||||
error "docker-compose.yml не найден. Запустите скрипт из корня проекта."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local start_time
|
||||
start_time=$(date +%s)
|
||||
|
||||
# Выполняем все этапы
|
||||
check_dependencies
|
||||
save_local_changes
|
||||
backup_to_remote "$backup_remote" "$remote_source"
|
||||
cleanup_staticfiles
|
||||
update_code "$remote_source"
|
||||
stop_containers
|
||||
build_images
|
||||
start_containers
|
||||
run_migrations
|
||||
collect_static
|
||||
health_check
|
||||
|
||||
local end_time
|
||||
end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
echo ""
|
||||
echo "🎉 Обновление завершено успешно!"
|
||||
echo "⏱️ Время выполнения: ${duration} секунд"
|
||||
echo "📡 Источник обновления: $remote_source"
|
||||
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 - Полное обновление из origin (по умолчанию)"
|
||||
echo " $0 origin - Обновление из origin репозитория"
|
||||
echo " $0 backup - Обновление из backup репозитория"
|
||||
echo " $0 origin backup - Обновление из origin с бэкапом в backup"
|
||||
echo " $0 backup origin - Обновление из backup с бэкапом в origin"
|
||||
echo " $0 --help - Показать эту справку"
|
||||
echo " $0 --logs - Показать логи без обновления"
|
||||
echo " $0 --status - Показать статус без обновления"
|
||||
echo ""
|
||||
echo "Примеры:"
|
||||
echo " $0 # обновление из origin"
|
||||
echo " $0 backup # обновление из backup репозитория"
|
||||
echo " $0 origin backup # обновление из origin, бэкап в backup"
|
||||
echo ""
|
||||
exit 0
|
||||
;;
|
||||
--logs)
|
||||
show_logs
|
||||
exit 0
|
||||
;;
|
||||
--status)
|
||||
docker-compose ps
|
||||
health_check
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# Передаем все параметры в main
|
||||
main "$@"
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user