feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile
- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
This commit is contained in:
133
app/services/deployment_service.py
Normal file
133
app/services/deployment_service.py
Normal file
@@ -0,0 +1,133 @@
|
||||
"""
|
||||
Сервис для развертывания ролей на реальные серверы
|
||||
Автор: Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from typing import Optional, AsyncGenerator, Dict, List
|
||||
from datetime import datetime
|
||||
from app.core.config import settings
|
||||
from app.core.ansible_executor import AnsibleExecutor
|
||||
|
||||
|
||||
class DeploymentService:
|
||||
"""Развертывание ролей на реальные серверы"""
|
||||
|
||||
def __init__(self):
|
||||
self.project_root = settings.PROJECT_ROOT
|
||||
self.inventory_file = self.project_root / "inventory" / "hosts.ini"
|
||||
self.deploy_playbook = self.project_root / "roles" / "deploy.yml"
|
||||
self.ansible_executor = AnsibleExecutor()
|
||||
|
||||
async def deploy_role(
|
||||
self,
|
||||
role_name: str,
|
||||
inventory: Optional[str] = None,
|
||||
limit: Optional[str] = None,
|
||||
tags: Optional[List[str]] = None,
|
||||
check: bool = False,
|
||||
extra_vars: Optional[Dict] = None,
|
||||
stream: bool = False
|
||||
) -> AsyncGenerator[str, None]:
|
||||
"""
|
||||
Развертывание роли на реальные серверы
|
||||
|
||||
Args:
|
||||
role_name: Имя роли для развертывания
|
||||
inventory: Путь к inventory файлу (по умолчанию inventory/hosts.ini)
|
||||
limit: Ограничение на хосты
|
||||
tags: Список тегов для фильтрации
|
||||
check: Режим dry-run (--check)
|
||||
extra_vars: Дополнительные переменные
|
||||
stream: Если True, возвращает генератор строк
|
||||
|
||||
Yields:
|
||||
Строки вывода команды
|
||||
"""
|
||||
# Проверка существования роли
|
||||
role_path = self.project_root / "roles" / role_name
|
||||
if not role_path.exists():
|
||||
yield f"❌ Роль '{role_name}' не найдена\n"
|
||||
return
|
||||
|
||||
# Определение inventory файла
|
||||
if inventory:
|
||||
inventory_path = Path(inventory)
|
||||
if not inventory_path.is_absolute():
|
||||
inventory_path = self.project_root / inventory_path
|
||||
else:
|
||||
inventory_path = self.inventory_file
|
||||
|
||||
if not inventory_path.exists():
|
||||
yield f"❌ Inventory файл '{inventory_path}' не найден\n"
|
||||
yield "💡 Создайте файл inventory/hosts.ini с вашими серверами\n"
|
||||
return
|
||||
|
||||
# Проверка deploy.yml
|
||||
if not self.deploy_playbook.exists():
|
||||
yield f"❌ Playbook '{self.deploy_playbook}' не найден\n"
|
||||
return
|
||||
|
||||
# Формирование тегов
|
||||
deploy_tags = [role_name]
|
||||
if tags:
|
||||
deploy_tags.extend(tags)
|
||||
|
||||
yield f"🚀 Развертывание роли '{role_name}' на реальные серверы...\n"
|
||||
if check:
|
||||
yield "⚠️ Режим dry-run (--check) - изменения не будут применены\n"
|
||||
yield f"📋 Inventory: {inventory_path}\n"
|
||||
if limit:
|
||||
yield f"📋 Limit: {limit}\n"
|
||||
yield f"📋 Tags: {', '.join(deploy_tags)}\n\n"
|
||||
|
||||
# Запуск ansible-playbook
|
||||
async for line in self.ansible_executor.run_playbook(
|
||||
playbook_path=str(self.deploy_playbook),
|
||||
inventory=str(inventory_path),
|
||||
tags=deploy_tags,
|
||||
limit=limit,
|
||||
check=check,
|
||||
extra_vars=extra_vars,
|
||||
stream=True
|
||||
):
|
||||
yield line
|
||||
|
||||
yield "\n✅ Развертывание завершено\n"
|
||||
|
||||
async def dry_run_role(
|
||||
self,
|
||||
role_name: str,
|
||||
inventory: Optional[str] = None,
|
||||
limit: Optional[str] = None,
|
||||
stream: bool = False
|
||||
) -> AsyncGenerator[str, None]:
|
||||
"""
|
||||
Dry-run проверка роли на реальных серверах (без изменений)
|
||||
|
||||
Args:
|
||||
role_name: Имя роли
|
||||
inventory: Путь к inventory файлу
|
||||
limit: Ограничение на хосты
|
||||
stream: Если True, возвращает генератор строк
|
||||
|
||||
Yields:
|
||||
Строки вывода команды
|
||||
"""
|
||||
yield f"🔍 Dry-run проверка роли '{role_name}' на реальных серверах...\n"
|
||||
yield "⚠️ Безопасно: не изменяет серверы, только проверяет\n\n"
|
||||
|
||||
async for line in self.deploy_role(
|
||||
role_name=role_name,
|
||||
inventory=inventory,
|
||||
limit=limit,
|
||||
check=True,
|
||||
stream=True
|
||||
):
|
||||
yield line
|
||||
|
||||
def detect_log_level(self, line: str) -> str:
|
||||
"""Определение уровня лога из строки"""
|
||||
return self.ansible_executor.detect_log_level(line)
|
||||
Reference in New Issue
Block a user