fix(disk-resize): honest task status, auto-grow FS, CRLF-safe guest exec

Backend fixes for VM/LXC disk resize:
- resize_vm_disk/resize_container_disk now honor wait_for_task and raise
  the real Proxmox exitstatus (e.g. "disk 'scsi0' does not exist") instead
  of always returning success.
- add grow_vm_filesystem: after a VM resize, rescan the disk (retry loop,
  needed for SATA/SCSI), growpart the partition and resize the FS
  (ext*/xfs/btrfs) via the guest agent; surface its output to the API.
- execute_script normalizes CRLF/CR to LF so pasted scripts and growpart
  don't break on trailing \r ("partition-number must be a number").

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 02:43:03 +05:00
parent 1a17ceed82
commit 38d485be4b
3 changed files with 135 additions and 23 deletions

View File

@@ -1390,9 +1390,32 @@ async def resize_vm_disk(
logger.info(f"Updated disk size in database: VM {vmid} -> {size_gb}GB")
logger.info(f"User {current_user.username} resized disk {disk} of VM {vmid} to {size}")
# Автоматически расширяем раздел и ФС внутри гостя (best-effort).
# Требует qemu-guest-agent и growpart в гостевой ОС; при их
# отсутствии ресайз диска всё равно считается успешным.
grow = client.grow_vm_filesystem(node, vmid)
grew = bool(grow.get('changed'))
# Включаем и error: если вызов guest agent упал с исключением,
# stdout/stderr пустые, и без error пользователь видел пустой блок.
grow_output = (
(grow.get('stdout', '') or '')
+ (grow.get('stderr', '') or '')
+ (grow.get('error', '') or '')
).strip() or 'growpart не вернул вывода (qemu-guest-agent не отвечает?)'
if grew:
message = f"Размер диска {disk} изменен на {size}. Файловая система автоматически расширена."
else:
message = (
f"Размер диска {disk} изменен на {size}, но файловую систему "
f"расширить не удалось — см. вывод growpart."
)
return JSONResponse(content={
"status": "success",
"message": f"Размер диска {disk} изменен на {size}. Для применения изменений внутри ОС выполните resize файловой системы."
"status": "success",
"message": message,
"filesystem_grown": grew,
"grow_output": grow_output,
})
else:
raise HTTPException(status_code=500, detail="Не удалось изменить размер диска")