fix(templates): автоматически сохранять короткое имя LXC как корректный Proxmox volid

This commit is contained in:
2026-08-09 23:10:40 +03:00
parent cbfe4139e3
commit 26a6e5b07f
+57 -6
View File
@@ -12,6 +12,47 @@ logger = logging.getLogger(__name__)
router = APIRouter(prefix="/templates", tags=["templates"]) router = APIRouter(prefix="/templates", tags=["templates"])
def _normalize_lxc_source(value: str | None) -> str | None:
"""Приводит источник LXC к корректному Proxmox volid.
Принимает как полный volid:
``local:vztmpl/debian-13-standard_13.6-1_amd64.tar.zst``
так и короткое имя:
``debian-13-standard_13.6-1_amd64``.
"""
if not value:
return None
source = value.strip()
if not source:
return None
# Если уже передан полный volid, оставляем его без изменений.
if ":" in source:
return source
# Сначала пытаемся найти точный volid среди шаблонов Proxmox.
# Это позволяет корректно обработать .tar.zst, .tar.gz и .tar.xz.
try:
for item in pve.list_lxc_templates():
if item.get("name") == source:
return item["volid"]
volid_name = item.get("volid", "").split("/")[-1]
if volid_name:
for extension in (".tar.zst", ".tar.gz", ".tar.xz"):
if volid_name.removesuffix(extension) == source:
return item["volid"]
except Exception as exc:
logger.warning("Не удалось сопоставить LXC-шаблон с Proxmox: %s", exc)
# Fallback для локального storage: короткое имя превращаем в volid.
for extension in (".tar.zst", ".tar.gz", ".tar.xz"):
if source.endswith(extension):
return f"local:vztmpl/{source}"
return f"local:vztmpl/{source}.tar.zst"
@router.get("", response_model=List[schemas.TemplateOut]) @router.get("", response_model=List[schemas.TemplateOut])
def list_templates(db: Session = Depends(get_db), _=Depends(get_current_user)): def list_templates(db: Session = Depends(get_db), _=Depends(get_current_user)):
"""Возвращает активные шаблоны, сохранённые в панели.""" """Возвращает активные шаблоны, сохранённые в панели."""
@@ -24,8 +65,21 @@ def create_template(
db: Session = Depends(get_db), db: Session = Depends(get_db),
_=Depends(require_admin), _=Depends(require_admin),
): ):
"""Добавляет шаблон в каталог панели.""" """Добавляет шаблон в каталог панели.
tpl = models.Template(**payload.model_dump())
Для LXC автоматически нормализует короткое имя архива в Proxmox volid.
"""
data = payload.model_dump()
if data.get("guest_type") == models.GuestType.lxc:
data["source_vmid"] = None
data["source_template"] = _normalize_lxc_source(data.get("source_template"))
if not data["source_template"]:
from fastapi import HTTPException
raise HTTPException(status_code=400, detail="Для LXC нужно указать архивный шаблон")
else:
data["source_template"] = None
tpl = models.Template(**data)
db.add(tpl) db.add(tpl)
db.commit() db.commit()
db.refresh(tpl) db.refresh(tpl)
@@ -34,10 +88,7 @@ def create_template(
@router.get("/from-proxmox") @router.get("/from-proxmox")
def list_proxmox_templates(_=Depends(require_admin)): def list_proxmox_templates(_=Depends(require_admin)):
"""Возвращает VM-шаблоны и архивные LXC-шаблоны с Proxmox. """Возвращает VM-шаблоны и архивные LXC-шаблоны с Proxmox."""
Готовые LXC-контейнеры по VMID намеренно не показываются.
"""
try: try:
vm_templates = pve.list_vm_templates() vm_templates = pve.list_vm_templates()
except Exception as exc: except Exception as exc: