Archived
71 lines
2.6 KiB
Python
71 lines
2.6 KiB
Python
from .config import settings
|
|
from .proxmox_client import _client, _wait_task
|
|
|
|
_VALID_ACTIONS = {"start", "stop", "shutdown", "reboot"}
|
|
|
|
|
|
def _is_not_found(error: Exception) -> bool:
|
|
"""Определяет ответ Proxmox об отсутствующем госте."""
|
|
if getattr(error, "status_code", None) == 404:
|
|
return True
|
|
response = getattr(error, "response", None)
|
|
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:
|
|
"""Останавливает и удаляет VM/LXC, ожидая завершения задач Proxmox."""
|
|
client = _client()
|
|
node = settings.pve_node
|
|
endpoint = _endpoint(client, guest_type, vmid)
|
|
try:
|
|
current = endpoint.status.current.get()
|
|
except Exception as error:
|
|
if _is_not_found(error):
|
|
return
|
|
raise
|
|
if current.get("status") == "running":
|
|
stop_upid = endpoint.status.stop.post()
|
|
if stop_upid:
|
|
_wait_task(client, node, stop_upid)
|
|
try:
|
|
delete_upid = endpoint.delete()
|
|
except Exception as error:
|
|
if _is_not_found(error):
|
|
return
|
|
raise
|
|
if 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)),
|
|
}
|