Archived
Добавлено создание VM и LXC из шаблона
This commit is contained in:
@@ -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,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user