mirror of
https://github.com/GoodOlClint/PSProxmoxVE.git
synced 2026-07-26 07:58:14 +00:00
fix: use qmpstatus for suspend state detection, fix SDN subnet ID format
Suspend/Resume:
- Poll status/current endpoint (not VM list) to get qmpstatus
- PVE reports status=running but qmpstatus=paused for suspended VMs
- Verified locally: Suspend-PveVm -Wait -Timeout 30 now works
SDN:
- Subnet IDs use zone prefix, not vnet: {zone}-{ip}-{prefix}
- Add 5s propagation delay before VNet deletion after subnet removal
- Switch to real Ubuntu 24.04 OVA for Import-PveOva testing
Integration tests:
- All VM/container lifecycle calls use -Wait -Timeout
- Remove manual Start-Sleep polling loops
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PSProxmoxVE.Core.Authentication;
|
||||
using PSProxmoxVE.Core.Client;
|
||||
using PSProxmoxVE.Core.Exceptions;
|
||||
using PSProxmoxVE.Core.Models.Vms;
|
||||
using PSProxmoxVE.Core.Services;
|
||||
@@ -69,25 +71,29 @@ namespace PSProxmoxVE.Cmdlets
|
||||
task = taskService.WaitForTask(session, node, task.Upid, null, null, null);
|
||||
}
|
||||
|
||||
// Then poll until VM/container reaches the expected status
|
||||
// Then poll status/current until VM/container reaches the expected status.
|
||||
// We query the status/current endpoint directly instead of the list endpoint
|
||||
// because it returns qmpstatus (needed for paused state detection — PVE reports
|
||||
// status=running but qmpstatus=paused for suspended VMs).
|
||||
var statusResource = isContainer
|
||||
? $"nodes/{node}/lxc/{vmid}/status/current"
|
||||
: $"nodes/{node}/qemu/{vmid}/status/current";
|
||||
|
||||
var deadline = DateTime.UtcNow.AddSeconds(timeoutSeconds);
|
||||
using var pollClient = new PveHttpClient(session);
|
||||
while (DateTime.UtcNow < deadline)
|
||||
{
|
||||
try
|
||||
{
|
||||
string? currentStatus;
|
||||
if (isContainer)
|
||||
{
|
||||
var ct = new ContainerService().GetContainer(session, node, vmid);
|
||||
currentStatus = ct.Status;
|
||||
}
|
||||
else
|
||||
{
|
||||
var vm = new VmService().GetVm(session, node, vmid);
|
||||
currentStatus = vm.Status;
|
||||
}
|
||||
var json = pollClient.GetAsync(statusResource).GetAwaiter().GetResult();
|
||||
var data = JObject.Parse(json)["data"];
|
||||
var status = data?["status"]?.ToString();
|
||||
var qmpStatus = data?["qmpstatus"]?.ToString();
|
||||
|
||||
if (string.Equals(currentStatus, expectedStatus, StringComparison.OrdinalIgnoreCase))
|
||||
// Use qmpstatus when available (more accurate for VM pause state)
|
||||
var effectiveStatus = qmpStatus ?? status;
|
||||
|
||||
if (string.Equals(effectiveStatus, expectedStatus, StringComparison.OrdinalIgnoreCase))
|
||||
return task;
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -773,8 +773,8 @@ Describe 'Integration Tests' -Tag 'Integration' {
|
||||
if (Skip-IfNoTarget) { return }
|
||||
if ($script:SkipSdn) { Set-ItResult -Skipped -Because $script:SkipSdn; return }
|
||||
|
||||
# PVE stores subnet IDs in the format: {vnet}-{ip}-{prefix}
|
||||
{ Remove-PveSdnSubnet -Vnet 'pestervn' -Subnet 'pestervn-10.99.0.0-24' `
|
||||
# PVE stores subnet IDs in the format: {zone}-{ip}-{prefix}
|
||||
{ Remove-PveSdnSubnet -Vnet 'pestervn' -Subnet 'pesterz-10.99.0.0-24' `
|
||||
-Confirm:$false -ErrorAction Stop } | Should -Not -Throw
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user