proxmox: Create by cloning a template, seed upload, config, start
Create validates placement, then under the per-name lock adopts the VM a previous attempt left (by name, or at a taken VMID after the ownership check of spec entry 2) or full-clones the template onto the UID's deterministic VMID with the mark in the clone call. It then uploads the seed over any existing file, writes cores, memory, agent, tag, ide2 and net0 when configured, grows the boot disk when diskGiB is larger, starts, and waits for running/running. waitUnlocked no longer waits on a suspended lock: a hibernated VM is judged at once, so ours is Permanent and a foreign one is probed past. The template is checked only on the allocation path, and its shape (net0, boot disk size) is refused before any clone exists. Spec entries 2, 4 and 10 updated to match. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -72,7 +72,12 @@ lands on the same number: `vmidFor(uid, attempt)` is
|
||||
seed step (entry 10). It is **foreign** when the name differs: move to
|
||||
the next attempt. The same name with no mark, or with a different
|
||||
non-empty `uid`, is `ErrPermanent` naming the VMID and both UIDs; the
|
||||
operator never takes over a VM it did not create.
|
||||
operator never takes over a VM it did not create. A `suspended` lock (a
|
||||
VM hibernated to disk) is not waited on: it is not a task and never
|
||||
clears by itself. Ownership is judged at once, as `Get` does (entry 9):
|
||||
a foreign hibernated VM is probed past, and ours is `ErrPermanent`
|
||||
(resume or destroy it), like kvm2's paused domain. Container and
|
||||
template entries at a VMID are foreign without a config read.
|
||||
|
||||
The wait in step 3 is what closes the duplicate-VM bug Phase 0 found: after
|
||||
a crash mid-clone, the retry's by-name lookup misses the nameless VM, but
|
||||
@@ -113,7 +118,12 @@ template may be edited, replaced or deleted without affecting running VMs.
|
||||
Before cloning, Create reads the template's config and refuses it with
|
||||
`ErrPermanent` when it is not a template (`template` is not 1) or when any
|
||||
disk slot holds a Proxmox cloud-init drive (a value containing `cloudinit`),
|
||||
which would compete with the provider's seed (entry 5). The template must
|
||||
which would compete with the provider's seed (entry 5). Because the clone
|
||||
copies the template's config, what the config or resize step would refuse
|
||||
on the clone is refused on the template too, before any VM exists: no
|
||||
`net0` while `bridge` or `vlanTag` is set, and no boot disk, or one
|
||||
without a readable `size=`, while `diskGiB` is set. A Permanent error
|
||||
after the clone would leave a VM that fixing the template cannot help. The template must
|
||||
boot from its first disk, run cloud-init with the NoCloud datasource, and
|
||||
either ship `qemu-guest-agent` or be able to install it (entry 7).
|
||||
|
||||
@@ -320,11 +330,15 @@ waits for the clone task first.
|
||||
Steps, each idempotent, in order, under the per-name lock (entry 19):
|
||||
|
||||
1. Validate placement (entry 3). No backend call yet.
|
||||
2. `GET /cluster/resources`. Find the template's node; a missing template
|
||||
is `ErrPermanent`. Read the template's config and refuse it as entry 4
|
||||
says.
|
||||
3. Find or allocate the VMID (entry 2). An adopted VM that is running
|
||||
returns its ID at once. An adopted VM that is stopped continues at step 5.
|
||||
2. `GET /cluster/resources` once, then look the name up (entry 2).
|
||||
3. When the name finds nothing: find the template's node (a missing
|
||||
template is `ErrPermanent`), read the template's config and refuse it as
|
||||
entry 4 says, then allocate the VMID (entry 2). The template is checked
|
||||
only here, because a VM that already exists no longer depends on it
|
||||
(entry 4): a template deleted after its clone must not fail that
|
||||
clone's adoption. An adopted VM, found by name or by the probe, gets one
|
||||
`status/current` read. Running, it returns its ID at once. Stopped, it
|
||||
continues at step 5.
|
||||
4. Clone and wait (clone budget).
|
||||
5. Build the seed and upload it to the VM's node, overwriting; wait
|
||||
(upload budget).
|
||||
|
||||
Reference in New Issue
Block a user