Computers

Clone a computer

Builds a new computer from a copy of this one’s current disk. The source is untouched, and must be stopped or suspended: a running source answers 409.

The answer arrives as soon as the new computer exists, with status: "building" while its disk is copied — poll it, or wait on its operation_id. The clone keeps the source’s size (size is a 400), lands stopped, and has no secrets bound.

Requires the member role or higher.

post/computers/{id}/clone

Request

  • Base URL: https://app.mandala.computer/api/v1
  • URL: https://app.mandala.computer/api/v1/computers/{id}/clone
  • Auth: HTTP bearer

Path parameters

idstring required

The computer id.

Headers

Idempotency-Keystring

Optional: a key of your choosing, 1 to 255 printable ASCII characters with no spaces (a UUID is ideal), that makes this call safe to send again after a lost answer. The call and its operation are recorded BEFORE it is carried out, so GET /operations?idempotency_key= finds it however the connection ended. For 24 hours, the same key with the byte-identical request (method, path, query and body, from a credential of the same scope) is not carried out again: it answers 409 idempotency_in_progress while the first is running, and the original answer — status and body, with Idempotent-Replayed: true — once it has finished. An answer too large to keep (over 1 MiB) is replayed instead as a 200 carrying {operation_id, operation}, also with Idempotent-Replayed: true: operation is the call’s operation, or null when there is none to show. Keys are kept per scope: a key used by a workspace's credential and the same key used by another workspace's, or by an account-wide one, are different keys, and neither is refused because of the other. A replayed body omits the desktop credentials the original carried (vnc, with its tokens and URLs): read the computer (GET /computers/{id}) for them. The same key on a different request is a 422 with code: "idempotency_key_reused", and a malformed key (empty, too long, outside printable ASCII, or the header sent twice) a 400 with code: "idempotency_key_invalid"; neither does anything. A call refused with a 4xx that did nothing releases its key, so it may be sent again under the same one. The exception is a delete whose 4xx says the computer was deleted — computer_deleted: true, or a purge result beside computer_deleted: false (it was deleted, then listed again): it happened, so its key keeps that answer and its operation is succeeded. Except a 409 with reason: "contention" whose purge deleted, queued and left in doubt nothing (the computer was already gone and copies in use refused the purge): nothing happened, so its key is released and the same request may be sent again under it. With computer_deleted: null, or false where the platform cannot confirm the computer was left in place, it is an unknown outcome: its key answers 409 idempotency_in_progress until the platform gives up on it, then 409 idempotency_outcome_unknown. A 5xx answer that names an operation_id is an unknown outcome too: that is the operation reserved for it. From then on the same key answers 409 idempotency_outcome_unknown, naming that operation (not idempotency_in_progress): read the computer, or the operation. The operation stays pending until the platform gives up on it; if it never learns how the call ended, it becomes failed with error.code: "lost". Some 5xx answers are refusals given before the call was sent anywhere — the platform could not check the account’s usage, or find a host for the call, for example — and some are a create or clone the host confirms it refused before building anything, such as a 503 from a host with no room left, and some are a start, restore or suspend the host confirms it refused before changing anything (a sealed session whose key could not be opened or whose transport failed first; on a suspend, suspend_outcome: "not_started"). Those name no operation_id: nothing was done, so the key is released as a 4xx refusal’s is, and the same call may be sent again under the same key. A host running older software cannot confirm such a refusal, so its 5xx is an unknown outcome like any other. A 5xx without an operation_id is not proof that nothing was done on its own: a call that records no operation (a PATCH that does not resize) names none, and neither does one whose operation could not be recorded. Sending the same call again under the same key is safe after any 5xx: it is carried out if its key was released, and answered 409 idempotency_outcome_unknown if not.

Request body

namestring

Name for the copy. Defaults to the source’s name followed by -clone. Cut to 64 characters, with control characters turned into spaces and the ends trimmed. A name left empty by that gets the default too.

Response

The new computer.

idstring

Stable identifier, e.g. vm-a1b2c3d4e5f6.

namestring

The name you gave it.

statusstring

running, stopped, suspended, building, build-failed or half-removed. The last is a computer whose deletion stopped partway and took its disk with it: every call that needs a disk is refused on it, it will never start again, and deleting it again is what clears it. A client that treats an unknown status as stopped will offer a start this API always refuses, so read these as a closed set and everything outside it as not startable. A running computer can be paused by its host without its status changing. When the host is low on disk space, the guests writing fastest are paused, and when it is critically low every running computer on it is paused, including ones that wrote nothing. Screenshots, input and commands stall or fail meanwhile, and the computer resumes by itself once space recovers. A suspend or memory snapshot that fails can also leave it paused: always when the failure says “this computer remains paused because the host is low on disk space”, and other failures can, at any free space. While the platform holds it for disk-space recovery, start, restart, suspend and snapshot answer 503 (“waiting for disk-space recovery”) until it resumes by itself once that recovery can finish, and a stop discards the paused session. Nor does any computer start or resume on a host that is low on disk space: a start, a restart of a stopped computer and the resume that using a suspended computer sets off answer 503 (“this host is low on disk space…”), and a restore answers 503 too, until space on that host has been freed.

osstring

linux or windows.

desktopstring

The display protocol this computer’s desktop speaks: wayland, x11, or absent (X11, or a host too old to say); branch on === "wayland". Screenshots, input and exec behave identically either way. What differs on a Wayland computer is that a window id is the compositor’s address rather than an X window id — opaque and handed back the same way, but not comparable across the two — and that moving or resizing a window the compositor is TILING is refused rather than silently ignored, because a tiled window’s geometry belongs to the layout. Read it here rather than from the template: a computer keeps the image it was built from, and a template’s version can advance underneath it.

templatestring

The template this computer was built from.

cpuinteger

Cores.

ram_mbinteger
disk_gbinteger
running_ram_mbinteger

The guest memory this computer is holding against your plan’s running pool: ram_mb while a process is live, or while a start or resume has been admitted and has not launched yet, and 0 otherwise. Non-zero BEFORE status says running, which is the point of publishing it — admission reserves the memory, and status is read from the guest process, which does not exist yet. So stopped with a non-zero value here is a cold boot on its way up, and suspended with one is a resume on its way up; 0 beside either means nothing has been admitted. Not proof that nothing will be: a start still waiting on this computer’s lifecycle lock has reserved nothing yet. ABSENT rather than 0 wherever this API cannot say — a host that could not be reached, a response written before the computer was read back (a create that answers with a start error, PATCH, either clone), or a host too old to report it. Absence means unknown, never zero.

resolutionstring

The screen this guest renders at, as WIDTHxHEIGHTxDEPTH. This is the coordinate space every click and every screenshot is in — size your model prompts from it rather than by decoding a PNG. Chosen at create and fixed for the life of the computer.

workspace_idstring

The workspace this computer is in. Absent when it is in none. It can change: a stopped computer can be moved to another workspace, or to none, with PUT /computers/{id}/workspace or from the dashboard.

created_atstring

RFC 3339 timestamp.

idle_suspend_mininteger

How long this computer may go untouched before its host suspends it. Absent on a computer with no override, which follows whatever its host is sweeping at. The host default is deliberately not reported in its place — it is a property of the host and it changes when an operator changes it.

egress_proxy_pendingboolean

Present and true while a running computer’s egress_proxy names credentials_secret_id and its host does not hold that secret’s value yet — just after a create or a change, after the host restarts, or once the secret is deleted. Every connection the computer opens meanwhile is closed, never sent directly; it usually clears within seconds. It does NOT clear by itself once the computer’s workspace is deleted: its egress credentials then resolve account-wide only, so a proxy naming one of that workspace’s own secrets is held closed until it is saved again naming an account-wide secret. Never present on a computer that is not running.

browser_proxy_pendingboolean

Present and true while a running computer’s guest does not have its browser_proxy yet — just after a create, a start or a change — or still has the files of one just removed. Wait for it to go away before starting a browser that must use the proxy. A browser already running when the setting changes applies it at its next start (Chromium usually within seconds). Never present on a computer that is not running: the setting is applied as it starts.

statestring

Whether this computer exists, as the platform’s own record has it — a different question from status, which is what its host says it is doing. live: its host lists it. unreachable: its host has not answered — on a listing row, for this request; the computer is most likely fine and nothing has been done to it. deleting: a delete was sent and not yet answered. deleted and lost are terminal, and are only ever shown when asked for with state=: deleted is a delete that was answered, lost is a computer whose host was written off by an operator while it was unreachable. Present on listing rows; absent on a single computer, which is served by its host and is therefore live.

deleted_atstring

RFC 3339 timestamp of the answered delete. Present once state has been deleted.

lost_atstring

RFC 3339 timestamp of the write-off. Present once state has been lost.

unreachableboolean

Present and true only on a row the platform served from its own record because the host holding this computer could not be reached. Such a row carries the computer’s identity — name, os, template, size, workspace_id, created_at, state — and nothing only its host knows: no status, no resolution. Its state is unreachable, or deleting when a delete is in flight for it. A listing with any such row carries X-GC-Incomplete, so you only ever see this after asking for a partial answer with allow_partial=1.

secrets_generationinteger

How many delivering starts this computer has had. Each cold start of a computer that holds secrets is one generation; the receipt below names the generation it is for, so a receipt whose generation is behind this one is from an earlier start.

secrets_errorstring

Why the last delivering start was stopped, in one fixed sentence naming the class of failure and never a value. A start whose delivery fails is stopped by the host and stays stopped until you start it again; this is the reason. Cleared when the next delivering start begins. Absent when the last delivery landed or none has been tried.

secrets_pendingboolean nullable

Whether this computer’s desktop is missing a change to its secrets that a restart would deliver: a binding, an env name or file, or a newer value it does not hold — or, once every secret has been removed, whether its running or saved session still holds the values it had. Compared against the receipt, so it clears once any delivery lands — a start, a restart from anywhere, a reboot inside it, or a secret file replaced while it runs — and stays after one that failed. A value replaced for a secret bound as a file is replaced live on a running computer, and is pending only if that did not land. One bound as an environment variable is the same on an image that hands new shells the current values: once they see it, it is not pending, though programs already running — the desktop session among them — keep the value they started with until a restart; on any other image it waits for a restart. A change that removed a secret, or moved one to another revision, stays pending until a restart either way, since the running session may still hold the old value. Only ever true of a running or suspended computer: a suspended one resumes with the values it had, and a stopped one gets everything current when it starts, so it is never pending. null when it could not be checked — the current values could not be read, or the computer’s last delivery predates the record of the names it was made under and it has been rebound since; a restart makes it known. A delivery still on its way is not pending — wait on secrets_delivering for that. Present whenever secrets is, and on a computer with no secrets bound only while true.

secrets_deliveringboolean

Whether values are on their way into this computer’s desktop right now. A computer comes back running a few seconds before its secrets land, and a command run in between sees them unset; after a create, a start or a restart, wait for this to be false before relying on them. Also true from the moment a restart, or a reboot inside the computer, clears them until they are delivered again, and while a replaced value is written to a file. Reported by the computer’s host, which is doing the delivering. False on a computer that is not running and after a delivery that failed (secrets_error says why, and the computer is stopped). After a restart or a reboot it can also go back to false with nothing delivered and no secrets_error: that is a computer that has not come back up three minutes after it, and its secrets are not in it — restart it, or stop and start it. While it reads true only because a restarted computer has not come back up yet, a further restart is accepted, since that is the way out of one that does not; once the delivery itself has begun, a restart answers 409 until it lands. Present whenever secrets is.

operation_idstring

Present only on the answer to a lifecycle call — a create, a clone, or a PATCH that resized — and never on a read: the operation it started, which GET /operations/{id} answers. A clone’s is running until its disk has been copied. Absent, with the call still done, in the rare case the operation could not be recorded; a client must not treat its absence as a failure of the call.

Changes

No recorded changes to this operation across all 1 revision of this API.