Создание LXC ограничено архивными шаблонами
This commit is contained in:
@@ -65,18 +65,10 @@ def _provision(instance_id: int, template_id: int, node: str) -> None:
|
|||||||
pve.configure_cloud_init(instance.vmid, instance.ciuser, instance.root_password, node)
|
pve.configure_cloud_init(instance.vmid, instance.ciuser, instance.root_password, node)
|
||||||
pve.guest_action("vm", instance.vmid, "start", node)
|
pve.guest_action("vm", instance.vmid, "start", node)
|
||||||
else:
|
else:
|
||||||
password = instance.root_password or pve.gen_password()
|
# LXC создаётся только из архивного шаблона vzdump.
|
||||||
if template.source_vmid:
|
# Готовые LXC-контейнеры по VMID намеренно не используются.
|
||||||
pve.clone_lxc(
|
if not template.source_template:
|
||||||
source_vmid=template.source_vmid,
|
raise ValueError("У LXC-шаблона не указан source_template")
|
||||||
new_vmid=instance.vmid,
|
|
||||||
name=clean_name,
|
|
||||||
cores=template.cores,
|
|
||||||
memory_mb=template.memory_mb,
|
|
||||||
password=password,
|
|
||||||
node=node,
|
|
||||||
)
|
|
||||||
elif template.source_template:
|
|
||||||
password = pve.create_lxc(
|
password = pve.create_lxc(
|
||||||
new_vmid=instance.vmid,
|
new_vmid=instance.vmid,
|
||||||
name=clean_name,
|
name=clean_name,
|
||||||
@@ -86,8 +78,6 @@ def _provision(instance_id: int, template_id: int, node: str) -> None:
|
|||||||
disk_gb=template.disk_gb,
|
disk_gb=template.disk_gb,
|
||||||
node=node,
|
node=node,
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
raise ValueError("У LXC-шаблона не указан source_vmid или source_template")
|
|
||||||
instance.root_password = password
|
instance.root_password = password
|
||||||
pve.guest_action("lxc", instance.vmid, "start", node)
|
pve.guest_action("lxc", instance.vmid, "start", node)
|
||||||
|
|
||||||
@@ -109,13 +99,7 @@ def create_instance(
|
|||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
user: models.User = Depends(get_current_user),
|
user: models.User = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
"""Регистрирует один инстанс и запускает его создание в фоне.
|
"""Регистрирует один инстанс и запускает его создание в фоне."""
|
||||||
|
|
||||||
Блокировка строки пользователя и проверка статуса creating не позволяют
|
|
||||||
повторному клику создать несколько VPS для одного пользователя.
|
|
||||||
"""
|
|
||||||
# Блокируем пользователя на время резервирования VMID и записи инстанса.
|
|
||||||
# Это защищает от двух почти одновременных POST-запросов из браузера.
|
|
||||||
db.query(models.User).filter(models.User.id == user.id).with_for_update().one()
|
db.query(models.User).filter(models.User.id == user.id).with_for_update().one()
|
||||||
pending = (
|
pending = (
|
||||||
db.query(models.Instance)
|
db.query(models.Instance)
|
||||||
@@ -126,10 +110,7 @@ def create_instance(
|
|||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
if pending:
|
if pending:
|
||||||
raise HTTPException(
|
raise HTTPException(status_code=409, detail="Предыдущий VPS ещё создаётся. Дождитесь завершения операции.")
|
||||||
status_code=409,
|
|
||||||
detail="Предыдущий VPS ещё создаётся. Дождитесь завершения операции.",
|
|
||||||
)
|
|
||||||
|
|
||||||
template = (
|
template = (
|
||||||
db.query(models.Template)
|
db.query(models.Template)
|
||||||
@@ -147,18 +128,14 @@ def create_instance(
|
|||||||
|
|
||||||
active = (
|
active = (
|
||||||
db.query(models.Instance)
|
db.query(models.Instance)
|
||||||
.filter(
|
.filter(models.Instance.vmid == vmid, models.Instance.status != models.InstanceStatus.deleted)
|
||||||
models.Instance.vmid == vmid,
|
|
||||||
models.Instance.status != models.InstanceStatus.deleted,
|
|
||||||
)
|
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
if active:
|
if active:
|
||||||
raise HTTPException(status_code=409, detail=f"VMID {vmid} уже используется в панели")
|
raise HTTPException(status_code=409, detail=f"VMID {vmid} уже используется в панели")
|
||||||
|
|
||||||
clean_name = _sanitize_name(payload.name)
|
|
||||||
instance = models.Instance(
|
instance = models.Instance(
|
||||||
name=clean_name,
|
name=_sanitize_name(payload.name),
|
||||||
vmid=vmid,
|
vmid=vmid,
|
||||||
node=settings.pve_node,
|
node=settings.pve_node,
|
||||||
guest_type=template.guest_type,
|
guest_type=template.guest_type,
|
||||||
@@ -258,7 +235,6 @@ def delete_instance(instance_id: int, db: Session = Depends(get_db), user: model
|
|||||||
_ensure_owner(instance, user)
|
_ensure_owner(instance, user)
|
||||||
if instance.status == models.InstanceStatus.deleting:
|
if instance.status == models.InstanceStatus.deleting:
|
||||||
raise HTTPException(status_code=409, detail="Инстанс уже удаляется")
|
raise HTTPException(status_code=409, detail="Инстанс уже удаляется")
|
||||||
|
|
||||||
instance.status = models.InstanceStatus.deleting
|
instance.status = models.InstanceStatus.deleting
|
||||||
db.commit()
|
db.commit()
|
||||||
try:
|
try:
|
||||||
@@ -268,7 +244,6 @@ def delete_instance(instance_id: int, db: Session = Depends(get_db), user: model
|
|||||||
instance.status = models.InstanceStatus.error
|
instance.status = models.InstanceStatus.error
|
||||||
db.commit()
|
db.commit()
|
||||||
raise HTTPException(status_code=502, detail=f"Ошибка удаления: {exc}")
|
raise HTTPException(status_code=502, detail=f"Ошибка удаления: {exc}")
|
||||||
|
|
||||||
instance.status = models.InstanceStatus.deleted
|
instance.status = models.InstanceStatus.deleted
|
||||||
db.commit()
|
db.commit()
|
||||||
return {"ok": True}
|
return {"ok": True}
|
||||||
|
|||||||
Reference in New Issue
Block a user