Files
DevOpsLab/app/services/history_service.py
Сергей Антропов 1fbf9185a2 feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile
- Добавлена колонка 'Тип' во все таблицы истории сборок
- Для push операций отображается registry вместо платформ
- Сохранение пользователя при создании push лога
- Исправлена ошибка с logger в push_docker_image endpoint
- Улучшено отображение истории сборок с визуальными индикаторами
2026-02-15 22:59:02 +03:00

227 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Сервис для работы с историей команд и тестов
Автор: Сергей Антропов
Сайт: 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()