left4me/l4d2web/services/l4d2_facade.py
2026-05-05 23:47:06 +02:00

77 lines
2.9 KiB
Python

import json
from pathlib import Path
from sqlalchemy import select
from l4d2host.instances import delete_instance, initialize_instance, start_instance, stop_instance
from l4d2host.logs import stream_instance_logs
from l4d2host.status import get_instance_status
from l4d2host.steam_install import SteamInstaller
from l4d2web.db import session_scope
from l4d2web.models import Blueprint, BlueprintOverlay, Overlay, Server
from l4d2web.services.spec_yaml import write_temp_spec
def build_server_spec_payload(server: Server, blueprint: Blueprint, overlay_names: list[str]) -> dict:
return {
"port": server.port,
"overlays": overlay_names,
"arguments": json.loads(blueprint.arguments),
"config": json.loads(blueprint.config),
}
def load_server_blueprint_bundle(server_id: int) -> tuple[Server, Blueprint, list[str]]:
with session_scope() as db:
server = db.scalar(select(Server).where(Server.id == server_id))
if server is None:
raise ValueError("server not found")
blueprint = db.scalar(select(Blueprint).where(Blueprint.id == server.blueprint_id))
if blueprint is None:
raise ValueError("blueprint not found")
rows = db.execute(
select(Overlay.name)
.join(BlueprintOverlay, BlueprintOverlay.overlay_id == Overlay.id)
.where(BlueprintOverlay.blueprint_id == blueprint.id)
.order_by(BlueprintOverlay.position)
).all()
overlay_names = [row[0] for row in rows]
return server, blueprint, overlay_names
def install_runtime(on_stdout=None, on_stderr=None) -> None:
SteamInstaller().install_or_update(on_stdout=on_stdout, on_stderr=on_stderr)
def initialize_server(server_id: int, on_stdout=None, on_stderr=None) -> None:
server, blueprint, overlay_names = load_server_blueprint_bundle(server_id)
spec_path = write_temp_spec(build_server_spec_payload(server, blueprint, overlay_names))
try:
initialize_instance(server.name, spec_path, on_stdout=on_stdout, on_stderr=on_stderr)
finally:
spec_path.unlink(missing_ok=True)
def start_server(server_id: int, on_stdout=None, on_stderr=None) -> None:
server, _, _ = load_server_blueprint_bundle(server_id)
start_instance(server.name, on_stdout=on_stdout, on_stderr=on_stderr)
def stop_server(server_id: int, on_stdout=None, on_stderr=None) -> None:
server, _, _ = load_server_blueprint_bundle(server_id)
stop_instance(server.name, on_stdout=on_stdout, on_stderr=on_stderr)
def delete_server(server_id: int, on_stdout=None, on_stderr=None) -> None:
server, _, _ = load_server_blueprint_bundle(server_id)
delete_instance(server.name, on_stdout=on_stdout, on_stderr=on_stderr)
def server_status(server_name: str):
return get_instance_status(server_name)
def stream_server_logs(server_name: str, *, lines: int = 200, follow: bool = True):
return stream_instance_logs(server_name, lines=lines, follow=follow)