bmc_hub/app/settings/backend/views.py

104 lines
3.2 KiB
Python
Raw Normal View History

"""
Settings Frontend Views
"""
2026-01-28 08:03:17 +01:00
from datetime import datetime
from pathlib import Path
2026-01-28 10:25:21 +01:00
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
2026-01-28 10:35:02 +01:00
from pydantic import BaseModel
2026-01-28 10:41:48 +01:00
import os
2026-01-28 10:47:29 +01:00
import shutil
2026-01-28 10:25:21 +01:00
import subprocess
2026-01-28 08:03:17 +01:00
from app.core.config import settings
router = APIRouter()
templates = Jinja2Templates(directory="app")
@router.get("/settings", response_class=HTMLResponse, tags=["Frontend"])
async def settings_page(request: Request):
"""Render settings page"""
return templates.TemplateResponse("settings/frontend/settings.html", {
"request": request,
"title": "Indstillinger"
})
2026-01-28 08:03:17 +01:00
@router.get("/settings/migrations", response_class=HTMLResponse, tags=["Frontend"])
async def migrations_page(request: Request):
"""Render database migrations page"""
migrations_dir = Path(__file__).resolve().parents[3] / "migrations"
migrations = []
if migrations_dir.exists():
for migration_file in sorted(migrations_dir.glob("*.sql")):
stat = migration_file.stat()
migrations.append({
"name": migration_file.name,
"size_kb": round(stat.st_size / 1024, 1),
"modified": datetime.fromtimestamp(stat.st_mtime).strftime("%Y-%m-%d %H:%M")
})
return templates.TemplateResponse("settings/frontend/migrations.html", {
"request": request,
"title": "Database Migrationer",
"migrations": migrations,
"db_user": settings.POSTGRES_USER,
"db_name": settings.POSTGRES_DB,
"db_container": "bmc-hub-postgres"
})
2026-01-28 10:25:21 +01:00
2026-01-28 10:35:02 +01:00
class MigrationExecution(BaseModel):
file_name: str
2026-01-28 10:25:21 +01:00
@router.post("/settings/migrations/execute", tags=["Frontend"])
2026-01-28 10:35:02 +01:00
def execute_migration(payload: MigrationExecution):
2026-01-28 10:25:21 +01:00
"""Execute a migration SQL file"""
migrations_dir = Path(__file__).resolve().parents[3] / "migrations"
2026-01-28 10:35:02 +01:00
migration_file = migrations_dir / payload.file_name
2026-01-28 10:25:21 +01:00
if not migration_file.exists():
raise HTTPException(status_code=404, detail="Migration file not found")
# Determine the container runtime (Podman or Docker)
2026-01-28 10:47:29 +01:00
runtime_preference = (settings.CONTAINER_RUNTIME or "").strip().lower()
available_runtimes = [cmd for cmd in ("podman", "docker") if shutil.which(cmd)]
if not available_runtimes:
raise HTTPException(status_code=500, detail="No container runtime (docker/podman) found in PATH")
if runtime_preference and runtime_preference in available_runtimes:
runtime = runtime_preference
else:
runtime = available_runtimes[0]
2026-01-28 10:41:48 +01:00
command = [
runtime,
"exec",
"-i",
"bmc-hub-postgres",
"psql",
"-U",
settings.POSTGRES_USER,
"-d",
settings.POSTGRES_DB,
]
migration_sql = migration_file.read_text()
result = subprocess.run(
command,
input=migration_sql,
capture_output=True,
text=True,
env={**os.environ, "PGPASSWORD": settings.POSTGRES_PASSWORD},
2026-01-28 10:35:02 +01:00
)
2026-01-28 10:25:21 +01:00
if result.returncode != 0:
raise HTTPException(status_code=500, detail=f"Migration failed: {result.stderr}")
return {"message": "Migration executed successfully", "output": result.stdout}