Forking
Copy a hibernated desktop into N independent desktops.
POST /v1/desktops/{id}/fork creates count new, independent desktops
from a single Hibernated source desktop's memory snapshot. It's a
copy-on-write clone, not a re-provision from scratch -- each fork starts
from exactly the guest state the source had when it last hibernated.
Not a stub anymore
Earlier versions of this API returned 501 Not Implemented for this
route. It's a real, working feature now.
Preconditions
The source desktop must be hibernated -- forking an awake desktop (or
one in any other state) is a 409 Conflict. If you just finished working
on a desktop and want to fork it, hibernate it first:
curl -sS -X POST "$BASE/desktops/$DESKTOP_ID/hibernate?wait=true" -H "$AUTH"
curl -sS -X POST "$BASE/desktops/$DESKTOP_ID/fork?wait=true" \
-H "$AUTH" -H 'Content-Type: application/json' \
-d '{"count": 3, "acknowledge_shared_state": true}'acknowledge_shared_state is mandatory
{ "count": 3, "acknowledge_shared_state": true }Because a fork is a memory-snapshot copy, every resulting desktop starts
with the same in-guest state as the source -- including any
credentials, session tokens, or SSH agent state that happened to be live
in memory at hibernate time. The API can't tell a "pristine" generation
(safe to duplicate) from one holding live secrets, so it refuses to guess:
acknowledge_shared_state must be explicitly true, or the request is
rejected 400. An omitted field is not treated as an implicit true
-- it parses as false and is rejected just the same as sending false
outright.
If your source desktop might hold anything you wouldn't want duplicated across N new desktops, rotate/revoke it before forking, or avoid putting it there in the first place.
Count
count must be in 1..=20 per request -- 400 outside that range. Ask
for exactly as many forks as you need; there's no bulk/unlimited mode.
Ephemeral forks
{ "count": 5, "acknowledge_shared_state": true, "ephemeral": true }Pass "ephemeral": true to make the resulting forks throwaway: each gets
a forced idle_timeout_secs of 900 (15 minutes), regardless of what the
source desktop's own idle_timeout_secs was, and -- per
TTL and auto-hibernate's ephemeral note
-- an ephemeral desktop auto-destroys (not just hibernates) once it
hits that idle timeout. This is the fit for fan-out workloads: spin up N
disposable copies for a batch of independent tasks, let the ones you
don't explicitly destroy clean themselves up.
Without ephemeral: true (the default, false), forks inherit the
source's idle_timeout_secs verbatim and behave like any other desktop --
they auto-hibernate at that timeout like normal, they don't self-destroy.
Forks come back Hibernated
A successful fork does not wake the new desktops. They're created
directly in the hibernated state -- wake each one on demand (per the
normal wake flow)
when you're ready to use it. This keeps a large fan-out (count: 20) cheap
until you actually need the compute.
Result shape
Like wake/hibernate/destroy, fork returns an
operation handle. On success, the
settled operation's result carries the new desktop ids:
{
"id": "...",
"desktop_id": "d_source...",
"kind": "fork",
"state": "succeeded",
"result": { "desktop_ids": ["d_1...", "d_2...", "d_3..."] },
"error": null
}See API reference: Desktops -- Fork a desktop for every parameter and status code.