Fix duplicate key error when creating VM with previously deleted VMID

- Modified save_vm_instance to check for soft-deleted records before insert
- If a soft-deleted record exists with same server_id+vmid, restore and update it
- Prevents 'duplicate key value violates unique constraint' errors
This commit is contained in:
2025-12-15 20:53:15 +05:00
parent b0450438da
commit 83626d94bc

View File

@@ -4090,7 +4090,7 @@ def save_vm_instance(
) -> VMInstance: ) -> VMInstance:
"""Save or update VM instance configuration""" """Save or update VM instance configuration"""
# Проверяем, существует ли уже запись # Проверяем, существует ли уже активная запись
existing = db.query(VMInstance).filter( existing = db.query(VMInstance).filter(
VMInstance.server_id == server_id, VMInstance.server_id == server_id,
VMInstance.vmid == vmid, VMInstance.vmid == vmid,
@@ -4120,34 +4120,68 @@ def save_vm_instance(
db.commit() db.commit()
db.refresh(existing) db.refresh(existing)
return existing return existing
else:
# Создаем новую запись # Проверяем, есть ли удалённая запись с тем же vmid (soft-deleted)
instance = VMInstance( deleted_existing = db.query(VMInstance).filter(
server_id=server_id, VMInstance.server_id == server_id,
vmid=vmid, VMInstance.vmid == vmid,
node=node, VMInstance.deleted_at != None
vm_type=vm_type, ).first()
name=name,
cores=cores, if deleted_existing:
memory=memory, # Восстанавливаем и обновляем удалённую запись
disk_size=disk_size, deleted_existing.node = node
ip_address=ip_address, deleted_existing.vm_type = vm_type
ip_prefix=ip_prefix, deleted_existing.name = name
gateway=gateway, deleted_existing.cores = cores
nameserver=nameserver, deleted_existing.memory = memory
cloud_init_user=cloud_init_user, deleted_existing.disk_size = disk_size
cloud_init_password=cloud_init_password, deleted_existing.ip_address = ip_address
ssh_keys=ssh_keys, deleted_existing.ip_prefix = ip_prefix
template_id=template_id, deleted_existing.gateway = gateway
template_name=template_name, deleted_existing.nameserver = nameserver
description=description, deleted_existing.cloud_init_user = cloud_init_user
extra_config=extra_config, deleted_existing.cloud_init_password = cloud_init_password
owner_id=owner_id deleted_existing.ssh_keys = ssh_keys
) deleted_existing.template_id = template_id
db.add(instance) deleted_existing.template_name = template_name
deleted_existing.description = description
deleted_existing.extra_config = extra_config
deleted_existing.owner_id = owner_id
deleted_existing.status = 'unknown'
deleted_existing.deleted_at = None # Восстанавливаем запись
deleted_existing.updated_at = func.now()
db.commit() db.commit()
db.refresh(instance) db.refresh(deleted_existing)
return instance return deleted_existing
# Создаем новую запись
instance = VMInstance(
server_id=server_id,
vmid=vmid,
node=node,
vm_type=vm_type,
name=name,
cores=cores,
memory=memory,
disk_size=disk_size,
ip_address=ip_address,
ip_prefix=ip_prefix,
gateway=gateway,
nameserver=nameserver,
cloud_init_user=cloud_init_user,
cloud_init_password=cloud_init_password,
ssh_keys=ssh_keys,
template_id=template_id,
template_name=template_name,
description=description,
extra_config=extra_config,
owner_id=owner_id
)
db.add(instance)
db.commit()
db.refresh(instance)
return instance
def get_vm_instance(db: Session, server_id: int, vmid: int) -> VMInstance: def get_vm_instance(db: Session, server_id: int, vmid: int) -> VMInstance: