diff --git a/backend/app/routers/instances.py b/backend/app/routers/instances.py index 56f2ed4..11d7584 100644 --- a/backend/app/routers/instances.py +++ b/backend/app/routers/instances.py @@ -65,29 +65,19 @@ def _provision(instance_id: int, template_id: int, node: str) -> None: pve.configure_cloud_init(instance.vmid, instance.ciuser, instance.root_password, node) pve.guest_action("vm", instance.vmid, "start", node) else: - password = instance.root_password or pve.gen_password() - if template.source_vmid: - pve.clone_lxc( - source_vmid=template.source_vmid, - 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( - new_vmid=instance.vmid, - name=clean_name, - template_volid=template.source_template, - cores=template.cores, - memory_mb=template.memory_mb, - disk_gb=template.disk_gb, - node=node, - ) - else: - raise ValueError("У LXC-шаблона не указан source_vmid или source_template") + # LXC создаётся только из архивного шаблона vzdump. + # Готовые LXC-контейнеры по VMID намеренно не используются. + if not template.source_template: + raise ValueError("У LXC-шаблона не указан source_template") + password = pve.create_lxc( + new_vmid=instance.vmid, + name=clean_name, + template_volid=template.source_template, + cores=template.cores, + memory_mb=template.memory_mb, + disk_gb=template.disk_gb, + node=node, + ) instance.root_password = password pve.guest_action("lxc", instance.vmid, "start", node) @@ -109,13 +99,7 @@ def create_instance( db: Session = Depends(get_db), 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() pending = ( db.query(models.Instance) @@ -126,10 +110,7 @@ def create_instance( .first() ) if pending: - raise HTTPException( - status_code=409, - detail="Предыдущий VPS ещё создаётся. Дождитесь завершения операции.", - ) + raise HTTPException(status_code=409, detail="Предыдущий VPS ещё создаётся. Дождитесь завершения операции.") template = ( db.query(models.Template) @@ -147,18 +128,14 @@ def create_instance( active = ( db.query(models.Instance) - .filter( - models.Instance.vmid == vmid, - models.Instance.status != models.InstanceStatus.deleted, - ) + .filter(models.Instance.vmid == vmid, models.Instance.status != models.InstanceStatus.deleted) .first() ) if active: raise HTTPException(status_code=409, detail=f"VMID {vmid} уже используется в панели") - clean_name = _sanitize_name(payload.name) instance = models.Instance( - name=clean_name, + name=_sanitize_name(payload.name), vmid=vmid, node=settings.pve_node, 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) if instance.status == models.InstanceStatus.deleting: raise HTTPException(status_code=409, detail="Инстанс уже удаляется") - instance.status = models.InstanceStatus.deleting db.commit() try: @@ -268,7 +244,6 @@ def delete_instance(instance_id: int, db: Session = Depends(get_db), user: model instance.status = models.InstanceStatus.error db.commit() raise HTTPException(status_code=502, detail=f"Ошибка удаления: {exc}") - instance.status = models.InstanceStatus.deleted db.commit() return {"ok": True}