Provisioning¶
Creating an instance turns a plan + location + image into a running VM. The pipeline is asynchronous, idempotent and rolls back on failure.


Request pipeline¶
POST /api/client/cloud (or admin application API)
│ validate form + semantic rules + entitlements
▼
── DB TRANSACTION (no provider calls inside) ──────────────
instance row (pending → scheduling)
scheduler decision + capacity reservation
VMID reservation from the connection range
IP allocation (IPv4 required, IPv6 soft-fail)
root volume row (pending)
task (INSTANCE_CREATE) with a step thread
── COMMIT ─────────────────────────────────────────────────
▼
ProvisionInstanceJob (queue pterocloud-tasks)
one tick per handle(): begin → clone → configure → cloud_init
→ network → boot → verify → finalize
Stages¶
| Step | What happens |
|---|---|
clone |
Clone the provider template; instance reserved → cloning. |
configure |
Apply resources (sockets/cores/memory/tags), grow-only disk resize. |
cloud_init |
Identity + network seed (user/password/ssh keys/IP config/DNS). |
network |
Attach the primary NIC on the mapped bridge (+ VLAN), read back the MAC. |
boot |
Set boot order/agent/onboot, start the VM. |
verify |
Confirm the provider reports running; a guest-agent timeout is a warning, never a failure. |
finalize |
Consume the VMID, convert capacity, mark the volume ready, store the reveal-once credential, complete the task. |
Each stage is idempotent, so a crashed worker re-enters the current step without executing anything twice. Every stage is bounded by a timeout; over budget triggers rollback.
Credentials¶
- A unique password is generated with the CSPRNG for every operation; it is never derived from the instance id, uuid, hostname, plan or customer.
- The login username follows the precedence instance explicit → image
default_username→ plan default → global default.rootis used only when the image explicitly declares it and root login is allowed. - The credential is stored encrypted with an expiry and a
revealed_atmarker. A reveal is a locked transaction that marks the row revealed and erases the secret before returning the plaintext, so a concurrent second call is denied. - A failed provision deletes the credential; a rebuild mints a new one.
Credential types: PASSWORD, SSH_KEY, PASSWORD_AND_SSH_KEY,
IMAGE_DEFINED. An image that supports only SSH requires a valid public key
(IMAGE_SSH_KEY_REQUIRED); an image supporting neither is blocked
(IMAGE_LOGIN_METHOD_UNSUPPORTED), always before any provider resource is
created.
Idempotency¶
- Request — the
Idempotency-Keyheader caches the created instance uuid; a replay answers200with the same instance (meta.idempotent_replay: true). - Task — complete/fail are idempotent; the job exits when the task is terminal.
- Stage — clone is proven by persisted state or adopted when the occupying guest carries our hostname; resize is grow-only; config PUTs converge.
- Provider op — a recorded UPID is the resume token; the poll path never re-issues the operation.
Failure handling¶
Any stage exception funnels into the rollback service: guests provably ours are
stopped and destroyed (deletion confirmed against provider truth); VMID/IP/
capacity reservations release in order; the volume row stays as an errored audit
trail; the instance lands in failed with a customer-safe message and the task
fails with the same code. When the guest destroy is rejected or unconfirmable,
the instance parks in rollback_failed with every reservation kept for admin
follow-up.
Customer visibility¶
Clients see the status ladder, the task (progress, current step, step thread) and the safe failure block. Provider coordinates (VMID, node, UPIDs, template ids) never appear in client payloads.
Rate limits¶
Instance creation is rate-limited per user (5/minute, 20/hour by default).
Related¶
- Console & SSH
- Troubleshooting: scheduler
PC-PROV-###in the error reference