Добавлены управление питанием и live-статистика

This commit is contained in:
2026-08-09 16:27:08 +03:00
parent fb4c485118
commit fa04a4092d
+36 -6
View File
@@ -1,6 +1,8 @@
from .config import settings from .config import settings
from .proxmox_client import _client, _wait_task from .proxmox_client import _client, _wait_task
_VALID_ACTIONS = {"start", "stop", "shutdown", "reboot"}
def _is_not_found(error: Exception) -> bool: def _is_not_found(error: Exception) -> bool:
"""Определяет ответ Proxmox об отсутствующем госте.""" """Определяет ответ Proxmox об отсутствующем госте."""
@@ -10,31 +12,59 @@ def _is_not_found(error: Exception) -> bool:
return getattr(response, "status_code", None) == 404 return getattr(response, "status_code", None) == 404
def _endpoint(client, guest_type: str, vmid: int):
"""Возвращает endpoint VM или LXC."""
node = settings.pve_node
return client.nodes(node).qemu(vmid) if guest_type == "vm" else client.nodes(node).lxc(vmid)
def delete_guest(guest_type: str, vmid: int) -> None: def delete_guest(guest_type: str, vmid: int) -> None:
"""Останавливает и удаляет VM/LXC, ожидая завершения задач Proxmox.""" """Останавливает и удаляет VM/LXC, ожидая завершения задач Proxmox."""
client = _client() client = _client()
node = settings.pve_node node = settings.pve_node
endpoint = client.nodes(node).qemu(vmid) if guest_type == "vm" else client.nodes(node).lxc(vmid) endpoint = _endpoint(client, guest_type, vmid)
try: try:
current = endpoint.status.current.get() current = endpoint.status.current.get()
except Exception as error: except Exception as error:
if _is_not_found(error): if _is_not_found(error):
return return
raise raise
# Proxmox не удаляет запущенную VM/LXC, поэтому сначала останавливаем её.
if current.get("status") == "running": if current.get("status") == "running":
stop_upid = endpoint.status.stop.post() stop_upid = endpoint.status.stop.post()
if stop_upid: if stop_upid:
_wait_task(client, node, stop_upid) _wait_task(client, node, stop_upid)
try: try:
delete_upid = endpoint.delete() delete_upid = endpoint.delete()
except Exception as error: except Exception as error:
if _is_not_found(error): if _is_not_found(error):
return return
raise raise
if delete_upid: if delete_upid:
_wait_task(client, node, delete_upid) _wait_task(client, node, delete_upid)
def guest_action(guest_type: str, vmid: int, action: str) -> None:
"""Выполняет start, stop, shutdown или reboot."""
if action not in _VALID_ACTIONS:
raise ValueError("Недопустимое действие")
client = _client()
node = settings.pve_node
endpoint = _endpoint(client, guest_type, vmid)
upid = getattr(endpoint.status, action).post()
if upid:
_wait_task(client, node, upid, timeout=300)
def get_live_stats(guest_type: str, vmid: int) -> dict:
"""Возвращает CPU, RAM, uptime и фактический статус гостя."""
client = _client()
status = _endpoint(client, guest_type, vmid).status.current.get()
return {
"status": status.get("status", "unknown"),
"cpu_pct": round(float(status.get("cpu", 0)) * 100, 1),
"memory_used_bytes": int(status.get("mem", 0)),
"memory_total_bytes": int(status.get("maxmem", 0)),
"disk_used_bytes": int(status.get("disk", 0)),
"disk_total_bytes": int(status.get("maxdisk", 0)),
"uptime_seconds": int(status.get("uptime", 0)),
}