Update docs and screenshots
CI / backend (pull_request) Canceled after 0s
CI / shell (pull_request) Canceled after 0s
CI / frontend (pull_request) Canceled after 0s
CI / arm64-smoke (pull_request) Canceled after 0s
CI / backend (push) Canceled after 0s
CI / shell (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / arm64-smoke (push) Canceled after 0s

This commit is contained in:
2026-07-25 10:26:29 +02:00
parent d6cda77aaf
commit 1f110866f5
170 changed files with 24657 additions and 3 deletions
+3
View File
@@ -0,0 +1,3 @@
from app.system.service import SystemControlService
__all__ = ["SystemControlService"]
+96
View File
@@ -0,0 +1,96 @@
from __future__ import annotations
import asyncio
import os
from dataclasses import dataclass
from app.core.config import get_settings
@dataclass(slots=True)
class SystemCommandResult:
accepted: bool
action: str
status: str
detail: str
def as_dict(self) -> dict[str, object]:
return {
"accepted": self.accepted,
"action": self.action,
"status": self.status,
"detail": self.detail,
}
class SystemControlService:
def __init__(self) -> None:
settings = get_settings()
self._enabled = settings.system_control_enabled
self._platform = os.name
self._helper = settings.system_control_helper
async def restart_service(self) -> dict[str, object]:
return (await self._run_helper(
action="restart-service",
helper_action="restart-service",
)).as_dict()
async def reboot_host(self) -> dict[str, object]:
return (await self._run_helper(
action="reboot-host",
helper_action="reboot-host",
)).as_dict()
async def _run_helper(
self,
*,
action: str,
helper_action: str,
) -> SystemCommandResult:
if not self._enabled:
return SystemCommandResult(
accepted=False,
action=action,
status="disabled",
detail="Systemkontrol er deaktiveret i serverkonfigurationen.",
)
if self._platform != "posix":
return SystemCommandResult(
accepted=False,
action=action,
status="unsupported-platform",
detail="Systemkontrol understoettes kun paa Linux/systemd-installationer.",
)
if not os.path.exists(self._helper):
return SystemCommandResult(
accepted=False,
action=action,
status="helper-missing",
detail="Systemkontrol-helperen findes ikke paa maskinen.",
)
process = await asyncio.create_subprocess_exec(
"sudo",
"-n",
self._helper,
helper_action,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await process.communicate()
if process.returncode != 0:
error_output = (stderr or stdout).decode("utf-8", errors="ignore").strip() or "Ukendt fejl"
return SystemCommandResult(
accepted=False,
action=action,
status="command-failed",
detail=f"Kunne ikke planlaegge handlingen: {error_output}",
)
return SystemCommandResult(
accepted=True,
action=action,
status="scheduled",
detail="Handling planlagt. Serveren kan blive utilgaengelig et kort oeje.",
)