import html from fastapi import APIRouter, Form from fastapi.responses import HTMLResponse from ..catalog import load_apps, save_apps from ..config import ( DEFAULT_APPFACTORY_HOST, DEFAULT_GITEA_ORG, DELETE_APP_SCRIPT, DEPLOY_SCRIPT, GENERATE_COMPOSE_SCRIPT, NEW_APP_SCRIPT, read_env_value, ) from ..shell import run_command from ..templates.layout import page, render_result router = APIRouter() @router.get("/", response_class=HTMLResponse) def index(): apps = load_apps() gitea_url = read_env_value("GITEA_URL", "") gitea_org = read_env_value("GITEA_ORG", DEFAULT_GITEA_ORG) host = read_env_value("APPFACTORY_HOST", DEFAULT_APPFACTORY_HOST) rows = "" for item in apps: app_id = html.escape(item.get("id", "")) status = html.escape(item.get("status", "")) docs = html.escape(item.get("docs", f"/apps/{app_id}/docs")) memory = item.get("memory", "") cpus = item.get("cpus", "") http_clone = html.escape(f"git clone {gitea_url}/{gitea_org}/{app_id}.git") ssh_clone = html.escape(f"git clone ssh://git@{host}:2222/{gitea_org}/{app_id}.git") memory_options = "" for value, label in [ ("", "Výchozí"), ("256m", "256 MB - malá služba"), ("512m", "512 MB - běžná služba"), ("1g", "1 GB - větší služba"), ("2g", "2 GB - náročná služba"), ]: selected = "selected" if memory == value else "" memory_options += f'' cpu_options = "" for value, label in [ ("", "Výchozí"), ("0.25", "0,25 CPU - velmi malá služba"), ("0.50", "0,50 CPU - běžná služba"), ("1.00", "1 CPU - celé jádro"), ("2.00", "2 CPU - náročná služba"), ]: selected = "selected" if cpus == value else "" cpu_options += f'' rows += f""" {app_id}
/apps/{app_id} {status} Swagger
Paměť je limit RAM. CPU určuje maximální podíl výpočetního výkonu. Příklad: 0,50 = polovina jádra, 1,00 = celé jádro.
Příkazy pro klonování
""" if not rows: rows = 'Zatím nejsou nasazené žádné aplikace.' return page( "Aplikace", f"""

Aplikace

Vytváření, nasazení, klonování, nastavení prostředků a mazání služeb.

+ Nová aplikace

Zálohy

Vytváření záloh a kopírování příkazů pro obnovu. Obnova je záměrně ruční a chráněná.

Spravovat zálohy

Nasazené aplikace

{rows}
Aplikace Status Dokumentace Prostředky Git Akce
""", ) @router.get("/new-app", response_class=HTMLResponse) def new_app_form(): return page( "Nová aplikace", """

Vytvořit novou aplikaci

Vytvoří Gitea repozitář, webhook, lokální workspace, první commit a nasadí službu.




← Zpět

""", ) @router.post("/new-app", response_class=HTMLResponse) def create_app(app_id: str = Form(...), app_name: str = Form(...), template: str = Form(...)): if template != "python-fastapi": return HTMLResponse("Nepodporovaná šablona", status_code=400) create_result = run_command([NEW_APP_SCRIPT, app_id, app_name]) deploy_result = run_command([DEPLOY_SCRIPT, app_id]) status = "OK" if create_result.returncode == 0 and deploy_result.returncode == 0 else "FAILED" return render_result( title=f"Vytvoření aplikace: {status}", back_url="/portal", sections=[ ("Výstup vytvoření", create_result.stdout), ("Chyba vytvoření", create_result.stderr), ("Výstup nasazení", deploy_result.stdout), ("Chyba nasazení", deploy_result.stderr), ], extra_link=f"/apps/{html.escape(app_id)}/docs", extra_label="Otevřít Swagger", ) @router.post("/delete-app", response_class=HTMLResponse) def delete_app(app_id: str = Form(...)): result = run_command([DELETE_APP_SCRIPT, app_id]) status = "OK" if result.returncode == 0 else "FAILED" return render_result( title=f"Smazání aplikace: {status}", back_url="/portal", sections=[("Výstup", result.stdout), ("Chyba", result.stderr)], ) @router.post("/update-resources", response_class=HTMLResponse) def update_resources(app_id: str = Form(...), memory: str = Form(""), cpus: str = Form("")): apps = load_apps() for item in apps: if item.get("id") == app_id: memory = memory.strip() cpus = cpus.strip() if memory: item["memory"] = memory else: item.pop("memory", None) if cpus: item["cpus"] = cpus else: item.pop("cpus", None) save_apps(apps) compose_result = run_command([GENERATE_COMPOSE_SCRIPT]) deploy_result = run_command([DEPLOY_SCRIPT, app_id]) status = "OK" if compose_result.returncode == 0 and deploy_result.returncode == 0 else "FAILED" return render_result( title=f"Úprava prostředků: {status}", back_url="/portal", sections=[ ("Výstup compose", compose_result.stdout), ("Chyba compose", compose_result.stderr), ("Výstup nasazení", deploy_result.stdout), ("Chyba nasazení", deploy_result.stderr), ], )