feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile
- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
This commit is contained in:
226
app/services/history_service.py
Normal file
226
app/services/history_service.py
Normal file
@@ -0,0 +1,226 @@
|
||||
"""
|
||||
Сервис для работы с историей команд и тестов
|
||||
Автор: Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Optional
|
||||
from sqlalchemy.orm import Session
|
||||
from app.models.database import (
|
||||
CommandHistory, TestResult, DeploymentHistory,
|
||||
ExportHistory, ImportHistory
|
||||
)
|
||||
from app.db.session import get_db
|
||||
|
||||
|
||||
class HistoryService:
|
||||
"""Сервис для работы с историей"""
|
||||
|
||||
def save_command(
|
||||
self,
|
||||
command: str,
|
||||
command_type: str,
|
||||
role_name: Optional[str] = None,
|
||||
preset_name: Optional[str] = None,
|
||||
status: str = "running",
|
||||
user: Optional[str] = None
|
||||
) -> int:
|
||||
"""Сохранение команды в историю"""
|
||||
db = next(get_db())
|
||||
try:
|
||||
cmd_history = CommandHistory(
|
||||
command=command,
|
||||
command_type=command_type,
|
||||
role_name=role_name,
|
||||
preset_name=preset_name,
|
||||
status=status,
|
||||
user=user,
|
||||
started_at=datetime.utcnow()
|
||||
)
|
||||
db.add(cmd_history)
|
||||
db.commit()
|
||||
db.refresh(cmd_history)
|
||||
return cmd_history.id
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def update_command(
|
||||
self,
|
||||
command_id: int,
|
||||
status: str,
|
||||
stdout: Optional[str] = None,
|
||||
stderr: Optional[str] = None,
|
||||
returncode: Optional[int] = None
|
||||
):
|
||||
"""Обновление команды после выполнения"""
|
||||
db = next(get_db())
|
||||
try:
|
||||
cmd = db.query(CommandHistory).filter(CommandHistory.id == command_id).first()
|
||||
if cmd:
|
||||
cmd.status = status
|
||||
cmd.stdout = stdout
|
||||
cmd.stderr = stderr
|
||||
cmd.returncode = returncode
|
||||
cmd.finished_at = datetime.utcnow()
|
||||
if cmd.started_at:
|
||||
duration = (cmd.finished_at - cmd.started_at).total_seconds()
|
||||
cmd.duration = int(duration)
|
||||
db.commit()
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def get_command_history(
|
||||
self,
|
||||
limit: int = 50,
|
||||
role_name: Optional[str] = None,
|
||||
command_type: Optional[str] = None
|
||||
) -> List[Dict]:
|
||||
"""Получение истории команд"""
|
||||
db = next(get_db())
|
||||
try:
|
||||
query = db.query(CommandHistory)
|
||||
|
||||
if role_name:
|
||||
query = query.filter(CommandHistory.role_name == role_name)
|
||||
if command_type:
|
||||
query = query.filter(CommandHistory.command_type == command_type)
|
||||
|
||||
commands = query.order_by(CommandHistory.started_at.desc()).limit(limit).all()
|
||||
|
||||
return [
|
||||
{
|
||||
"id": cmd.id,
|
||||
"command": cmd.command,
|
||||
"command_type": cmd.command_type,
|
||||
"role_name": cmd.role_name,
|
||||
"preset_name": cmd.preset_name,
|
||||
"status": cmd.status,
|
||||
"started_at": cmd.started_at.isoformat() if cmd.started_at else None,
|
||||
"finished_at": cmd.finished_at.isoformat() if cmd.finished_at else None,
|
||||
"duration": cmd.duration
|
||||
}
|
||||
for cmd in commands
|
||||
]
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def save_test_result(
|
||||
self,
|
||||
command_id: int,
|
||||
role_name: str,
|
||||
preset_name: Optional[str],
|
||||
test_type: str,
|
||||
status: str,
|
||||
output: Optional[str] = None,
|
||||
error: Optional[str] = None,
|
||||
duration: Optional[int] = None
|
||||
) -> int:
|
||||
"""Сохранение результата теста"""
|
||||
db = next(get_db())
|
||||
try:
|
||||
test_result = TestResult(
|
||||
command_id=command_id,
|
||||
role_name=role_name,
|
||||
preset_name=preset_name,
|
||||
test_type=test_type,
|
||||
status=status,
|
||||
output=output,
|
||||
error=error,
|
||||
duration=duration,
|
||||
created_at=datetime.utcnow()
|
||||
)
|
||||
db.add(test_result)
|
||||
db.commit()
|
||||
db.refresh(test_result)
|
||||
return test_result.id
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def save_deployment(
|
||||
self,
|
||||
role_name: str,
|
||||
inventory: str,
|
||||
hosts: List[str],
|
||||
status: str,
|
||||
output: Optional[str] = None,
|
||||
error: Optional[str] = None,
|
||||
user: Optional[str] = None
|
||||
) -> int:
|
||||
"""Сохранение истории деплоя"""
|
||||
db = next(get_db())
|
||||
try:
|
||||
deployment = DeploymentHistory(
|
||||
role_name=role_name,
|
||||
inventory=inventory,
|
||||
hosts=hosts,
|
||||
status=status,
|
||||
output=output,
|
||||
error=error,
|
||||
user=user,
|
||||
started_at=datetime.utcnow()
|
||||
)
|
||||
db.add(deployment)
|
||||
db.commit()
|
||||
db.refresh(deployment)
|
||||
return deployment.id
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def save_export(
|
||||
self,
|
||||
role_name: str,
|
||||
repo_url: str,
|
||||
branch: str,
|
||||
version: Optional[str],
|
||||
commit_hash: Optional[str],
|
||||
status: str,
|
||||
user: Optional[str] = None
|
||||
) -> int:
|
||||
"""Сохранение истории экспорта"""
|
||||
db = next(get_db())
|
||||
try:
|
||||
export = ExportHistory(
|
||||
role_name=role_name,
|
||||
repo_url=repo_url,
|
||||
branch=branch,
|
||||
version=version,
|
||||
commit_hash=commit_hash,
|
||||
status=status,
|
||||
user=user,
|
||||
started_at=datetime.utcnow(),
|
||||
finished_at=datetime.utcnow() if status != "running" else None
|
||||
)
|
||||
db.add(export)
|
||||
db.commit()
|
||||
db.refresh(export)
|
||||
return export.id
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def save_import(
|
||||
self,
|
||||
role_name: str,
|
||||
source_type: str,
|
||||
source_url: Optional[str],
|
||||
status: str,
|
||||
user: Optional[str] = None
|
||||
) -> int:
|
||||
"""Сохранение истории импорта"""
|
||||
db = next(get_db())
|
||||
try:
|
||||
import_history = ImportHistory(
|
||||
role_name=role_name,
|
||||
source_type=source_type,
|
||||
source_url=source_url,
|
||||
status=status,
|
||||
user=user,
|
||||
started_at=datetime.utcnow(),
|
||||
finished_at=datetime.utcnow() if status != "running" else None
|
||||
)
|
||||
db.add(import_history)
|
||||
db.commit()
|
||||
db.refresh(import_history)
|
||||
return import_history.id
|
||||
finally:
|
||||
db.close()
|
||||
Reference in New Issue
Block a user