Добавлено создание VM и LXC из шаблона

This commit is contained in:
2026-08-09 14:47:29 +03:00
parent 4e4ae94182
commit f84ea52b05
+82 -2
View File
@@ -1,11 +1,15 @@
from fastapi import APIRouter, Depends
import logging
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.orm import Session
from .. import models, schemas
from .. import models, proxmox_client as pve, schemas
from ..config import settings
from ..database import get_db
from ..deps import get_current_user
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/instances", tags=["instances"])
@@ -22,3 +26,79 @@ def list_instances(
query = query.where(models.Instance.owner_id == user.id)
query = query.order_by(models.Instance.created_at.desc())
return list(db.scalars(query))
def _save_error(db: Session, instance: models.Instance, exc: Exception) -> None:
"""Помечает инстанс ошибочным, не сохраняя секреты или детали API."""
instance.status = models.InstanceStatus.error
db.commit()
logger.exception("Ошибка провижининга instance_id=%s: %s", instance.id, exc)
@router.post("", response_model=schemas.InstanceCreateOut, status_code=status.HTTP_201_CREATED)
def create_instance(
payload: schemas.InstanceCreate,
db: Session = Depends(get_db),
user: models.User = Depends(get_current_user),
):
"""Создаёт и запускает VM/LXC из активного шаблона.
Операция синхронная и может занимать несколько минут; очередь задач будет
добавлена следующим этапом.
"""
template = db.scalar(
select(models.Template).where(
models.Template.id == payload.template_id,
models.Template.is_active.is_(True),
)
)
if template is None:
raise HTTPException(status_code=404, detail="Активный шаблон не найден")
vmid = pve.next_vmid()
instance = models.Instance(
name=payload.name,
vmid=vmid,
node=settings.pve_node,
guest_type=template.guest_type,
status=models.InstanceStatus.creating,
owner_id=user.id,
template_id=template.id,
)
db.add(instance)
db.commit()
db.refresh(instance)
try:
if template.guest_type == models.GuestType.vm:
pve.provision_vm(
source_vmid=template.source_vmid,
vmid=vmid,
name=payload.name,
cores=template.cores,
memory_mb=template.memory_mb,
disk_gb=template.disk_gb,
username=payload.username,
password=payload.password,
)
else:
pve.provision_lxc(
source_template=template.source_template,
vmid=vmid,
name=payload.name,
cores=template.cores,
memory_mb=template.memory_mb,
disk_gb=template.disk_gb,
password=payload.password,
)
except Exception as exc:
_save_error(db, instance, exc)
raise HTTPException(status_code=502, detail="Не удалось создать инстанс в Proxmox")
instance.status = models.InstanceStatus.running
db.commit()
db.refresh(instance)
return schemas.InstanceCreateOut(
**schemas.InstanceOut.model_validate(instance).model_dump(),
initial_password=payload.password,
)