proxmox: Get, ListByTag and task polling
Get follows spec entry 9's check order (lock and unknown status before the name, suspended is Stopped after the name and mark checks), reads status/current so paused is Stopped, and maps the three agent messages of entry 7. ListByTag reads one config per candidate and fails whole only on the resources call or an ended ctx. waitTask polls the UPID's node every budgets.poll, logs failed tasks at V(1) and counts "WARNINGS: <n>" as success; waitUnlocked serves Create's ownership check. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -285,6 +285,11 @@ and starts it; the reconciler has no ID for it to `Get`.
|
||||
| `status: running`, any other `qmpstatus` (`paused`, `suspended`, `io-error`, …) | `status/current` | Stopped |
|
||||
| any other `status` | `status/current` | Stopped |
|
||||
|
||||
A `suspended` lock decides the state but not ownership: the config is still
|
||||
read, and a foreign name or a missing mark is still `ErrNotFound`, so a
|
||||
hibernated VM that reused our VMID is never reported as ours. Only
|
||||
`status/current` and the agent are skipped for it.
|
||||
|
||||
`status/current` is read, not only the resources entry, because a paused VM
|
||||
shows as plain `running` in `/cluster/resources`. `UID` and `CreatedAt` come
|
||||
from the description on every call. A running `Get` makes four calls:
|
||||
@@ -301,9 +306,10 @@ contract §2.2 and §4.11.
|
||||
`backend-lock`. Clone, upload, resize, start, stop, destroy and volume
|
||||
delete each return a UPID; the provider polls
|
||||
`GET /nodes/{node}/tasks/{upid}/status` every second until `status` is
|
||||
`stopped`, then reads `exitstatus`: `OK` is success, anything else is
|
||||
`ErrTransient` carrying that text. The node comes from the UPID
|
||||
(`UPID:<node>:…`). The handle is held within the call only: Create blocks
|
||||
`stopped`, then reads `exitstatus`: `OK` is success, and so is
|
||||
`WARNINGS: <n>`, which Proxmox itself counts as a finished task (logged at
|
||||
V(1)); anything else is `ErrTransient` carrying that text. The node comes
|
||||
from the UPID (`UPID:<node>:…`). The handle is held within the call only: Create blocks
|
||||
until the VM runs, so no handle outlives it, and a failure surfaces as
|
||||
Create's own error with the task's message. Locks: a VM locked by a task is
|
||||
waited on in Create (the ownership check) and reported as `ErrTransient` by
|
||||
@@ -447,7 +453,7 @@ per-parameter map. One `classify(op string, err error)`:
|
||||
| 500 `unable to create VM <vmid>: config file already exists` | handled by the allocator (entry 2); Transient if it escapes | the VMID is taken |
|
||||
| 500 `QEMU guest agent is not running`, `No QEMU guest agent configured`, `VM <vmid> is not running` | handled by `Get` (entry 7); Transient if they escape | agent state |
|
||||
| any other 5xx, including pveproxy's 595 and 596 | Transient | unknown means retry |
|
||||
| task `exitstatus` other than `OK` | Transient, with the text | the task failed; the next attempt retries |
|
||||
| task `exitstatus` other than `OK` or `WARNINGS: <n>` | Transient, with the text | the task failed; the next attempt retries |
|
||||
| TLS verification failure (`x509.UnknownAuthorityError`, `x509.HostnameError`, `x509.CertificateInvalidError`) | Permanent | wrong URL or CA file; the admin must act |
|
||||
| token file missing (`fs.ErrNotExist`) | Transient | the Secret has not landed yet |
|
||||
| token file present but not `<user>@<realm>!<id>=<secret>` | Permanent | wrong content in the Secret |
|
||||
|
||||
Reference in New Issue
Block a user