Cubicle

Boxes

The Boxes class of @cubicle/sdk: its constructor, properties and methods.

Box management, as cubicle.boxes. Every method that acts on one Box takes a Box reference: its ID, ORG/NAME, or a bare NAME (narrowed by the client's org or the API key's organization).

See

Using the SDK

Constructors

Constructor

new Boxes(context): Boxes;

Internal

Parameters

ParameterType
contextBoxesContext

Returns

Boxes

Methods

create()

create(params?, options?): Promise<Box>;

Creates a Box and, unless start is false or wait is false, waits until it is ready. When the wait fails, the Box still exists: CubicleBoxError carries its record, as does CubicleTimeoutError once a poll has succeeded, and repeating the create with the same idempotencyKey returns it.

The caller gets a grant on the new Box, so it can run commands there. The wait lasts up to 5 minutes unless timeoutMs says otherwise.

Parameters

ParameterTypeDescription
params?CreateBoxParamsWhat to create. Omitted sizes come from the base image.
options?CreateBoxOptionsWaiting, and the idempotency key.

Returns

Promise<Box>

A handle for the new Box.

Throws

CubicleApiError when the API refuses the request, for example with conflict (the name is taken), capacity (no Node can place the Box), box_create_disabled or idempotency_conflict.

Throws

CubicleTimeoutError when the Box is not ready in time.

Throws

CubicleBoxError when the Box fails to start (box_failed), or another request stops or deletes it (box_superseded).

Example

import { Cubicle } from "@cubicle/sdk"

const cubicle = new Cubicle()
const box = await cubicle.boxes.create({ name: "job-1", vcpus: 4, memoryMiB: 8192 })
console.log(box.id, box.org.name) // => "8d0c6a8e-…" "acme"

// Create it stopped, without waiting.
const later = await cubicle.boxes.create({ name: "job-2", start: false })

delete()

delete(ref, options?): Promise<void>;

Deletes the Box and its disk, and waits until its Node has removed them and released the Box's CPU, memory and disk. The Box stops resolving by name or ID as soon as the deletion is accepted.

Deleting also removes every snapshot of the Box. It cannot be undone. The Box is looked up first and deleted by ID, so a retry cannot reach a newer Box that took its name, and a retry that finds the Box already deleted counts as success.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
options?LifecycleOptionswait: false resolves once the deletion is accepted; timeoutMs (default 5 minutes) and signal control the wait.

Returns

Promise<void>

Throws

CubicleApiError with code not_found when the reference does not resolve, which includes a Box already being deleted, or conflict while a snapshot or restore of the Box is in progress or another Box is still being created from one of its snapshots, or forbidden without a grant on the Box or the owner or admin role in its organization.

Throws

CubicleTimeoutError when the Node has not removed the Box in time.

Example

await cubicle.boxes.delete("acme/job-1")

exec()

exec(
   ref, 
   argv, 
   options?
): Promise<ExecResult>;

Runs argv (no shell; use ["sh", "-c", "…"] for one) as the caller's guest account and waits for it to finish. Rejects with CubicleOperationError if the operation fails or its outcome is unknown; a command is never run twice.

The caller needs an explicit grant on the Box; it has one on Boxes it created. Output arrives when the command ends: there is no streaming, stdin or terminal.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
argvstring[]The program and its arguments.
options?ExecOptionsWorking directory, command timeout, output limit and wake.

Returns

Promise<ExecResult>

The exit code, output and operation ID.

Throws

CubicleApiError with code conflict when the Box is not running (pass wake: true), or forbidden without a grant on the Box.

Throws

CubicleOperationError when the operation fails, or ends unknown.

Throws

CubicleTimeoutError when no result arrives within the command's timeout plus 2 minutes (last is the Operation, once a poll has succeeded), or, with wake, when the Box is not ready within 5 minutes.

Example

const result = await cubicle.boxes.exec("acme/job-1", ["sh", "-c", "echo hello"])
console.log(result) // => { exitCode: 0, stdout: "hello\n", stderr: "", timedOut: false, … }

// Start the Box first if it is stopped or hibernated.
await cubicle.boxes.exec("acme/job-1", ["make", "test"], { wake: true, timeoutMs: 300_000 })

get()

get(ref, options?): Promise<BoxInfo>;

The Box's current record. Never changes the Box.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
options?SignalOptions-

Returns

Promise<BoxInfo>

Throws

CubicleApiError with code not_found when no Box the caller can see has that reference (Boxes being deleted no longer resolve), or ambiguous_box when a bare name matches Boxes in several organizations.

Example

const info = await cubicle.boxes.get("acme/job-1")
console.log(info.state, info.ssh.ready) // => "running" true

hibernate()

hibernate(ref, options?): Promise<BoxInfo>;

Saves the running Box's memory to disk and stops it; start resumes it.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
options?LifecycleOptionswait: false resolves once the request is accepted; timeoutMs (default 5 minutes) and signal control the wait.

Returns

Promise<BoxInfo>

The Box's record: once hibernated, or as accepted with wait: false.

Throws

CubicleApiError with code conflict when the Box is neither running nor already hibernated, must be started again after its host restarted, or has a snapshot or restore in progress, or forbidden without a grant on the Box or the owner or admin role in its organization.

Throws

CubicleBoxError with code hibernation_failed when saving fails: the Box keeps running and Cubicle retries at hibernationRetryAt.

Throws

CubicleTimeoutError when it is not hibernated in time.

Example

await cubicle.boxes.hibernate("acme/job-1")
await cubicle.boxes.start("acme/job-1") // resumes with memory and processes intact

list()

list(options?): AsyncGenerator<BoxInfo, void, undefined>;

Boxes in one organization (org, or the client's), or else in every organization the caller belongs to. An API key sees only its own organization. Boxes being deleted are listed, with deletion: "pending", until their Node has removed them.

The whole listing is fetched in one request when iteration starts.

Parameters

ParameterTypeDescription
options?{ org?: string; signal?: AbortSignal; }-
options.org?stringOrganization name or ID. Defaults to the client's org.
options.signal?AbortSignalAborts the request.

Returns

AsyncGenerator<BoxInfo, void, undefined>

Example

for await (const info of cubicle.boxes.list()) {
  if (info.deletion === "pending") continue // being deleted
  console.log(info.name, info.state)
}

listOperations()

listOperations(ref, options?): Promise<Operation[]>;

The Box's 50 most recent operations, newest first. An exec's result is null unless the caller requested it.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
options?SignalOptions-

Returns

Promise<Operation[]>


listSnapshots()

listSnapshots(ref, options?): Promise<Snapshot[]>;

The Box's snapshots, newest first, including pending and failed ones.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
options?SignalOptions-

Returns

Promise<Snapshot[]>


ref()

Call Signature

ref(ref): BoxRef;

A handle for a Box, without a network request. It addresses the Box by ref, so it may name a Box that does not exist; its first call reports that.

Parameters
ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
Returns

BoxRef

Example
const job = cubicle.boxes.ref("acme/job-1") // no request yet
await job.stop()

Call Signature

ref(box): Box;

A handle for a Box, without a network request. It addresses the Box by the record's ID, so it keeps reaching that Box even if its name is later reused.

Parameters
ParameterTypeDescription
boxBoxInfoA record from get or list.
Returns

Box

Example
const info = await cubicle.boxes.get("acme/job-1")
const job = cubicle.boxes.ref(info)
console.log(job.id, job.name) // => "8d0c6a8e-…" "job-1"

restore()

restore(
   ref, 
   snapshotId, 
   options?
): Promise<Operation>;

Restores a stopped Box's disk from one of its snapshots, in place, and waits.

Every file on the Box's disk is replaced. The Box keeps its ID, name, address and grants, and stays stopped: start it afterwards.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
snapshotIdstringA completed snapshot of this same Box.
options?OperationOptionstimeoutMs (default 15 minutes), signal and idempotencyKey.

Returns

Promise<Operation>

The finished restore operation.

Throws

CubicleApiError with code conflict when the Box is not stopped or the snapshot is not complete, not_found when the snapshot is not one of the Box's, or forbidden without a grant on the Box or the owner or admin role in its organization.

Throws

CubicleOperationError when the restore fails.

Throws

CubicleTimeoutError when it does not finish in time.

Example

const snapshots = await cubicle.boxes.listSnapshots("acme/job-1")
const before = snapshots.find((s) => s.name === "before-upgrade" && s.status === "complete")

if (before) {
  await cubicle.boxes.stop("acme/job-1")
  await cubicle.boxes.restore("acme/job-1", before.id)
  await cubicle.boxes.start("acme/job-1")
}

snapshot()

snapshot(
   ref, 
   name, 
   options?
): Promise<Snapshot>;

Snapshots a stopped Box's disk (not its memory) and waits for the snapshot to complete.

Stop the Box first, and let the stop finish: a hibernated Box must be stopped too, which discards its saved memory. The snapshot stays on the Box's Node and is deleted with the Box.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
namestring1 to 63 lowercase letters, digits, ., _ and -, starting with a letter or digit. Names need not be unique.
options?OperationOptionstimeoutMs (default 15 minutes), signal and idempotencyKey.

Returns

Promise<Snapshot>

The completed snapshot.

Throws

CubicleApiError with code conflict when the Box is not stopped, or forbidden without a grant on the Box or the owner or admin role in its organization.

Throws

CubicleOperationError when the snapshot fails.

Throws

CubicleTimeoutError when it does not complete in time.

Example

await cubicle.boxes.stop("acme/job-1")
const snapshot = await cubicle.boxes.snapshot("acme/job-1", "before-upgrade")
console.log(snapshot.id, snapshot.status) // => "3e5a…" "complete"

start()

start(ref, options?): Promise<BoxInfo>;

Starts the Box, or resumes it from hibernation, and waits until it is ready.

Starting a Box that is already running does not reboot it, but it advances the Box's generation: SSH and private-network traffic cannot reach the Box until its Node has applied it, open connections may not survive the gap, and the 60-minute hibernation clock starts again. A start also clears restartRequired.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
options?LifecycleOptionswait: false resolves once the request is accepted; timeoutMs (default 5 minutes) and signal control the wait.

Returns

Promise<BoxInfo>

The Box's record: once ready, or as accepted with wait: false.

Throws

CubicleApiError with code conflict while a snapshot or restore of the Box is in progress, or forbidden without a grant on the Box or the owner or admin role in its organization.

Throws

CubicleBoxError when the Box fails to start (box_failed) or another request changes its desired state (box_superseded).

Throws

CubicleTimeoutError when it is not ready in time.

Example

const info = await cubicle.boxes.start("acme/job-1")
console.log(info.ssh.ready) // => true

stop()

stop(ref, options?): Promise<BoxInfo>;

Stops the Box, discarding saved memory but keeping its disk, and waits until stopped. The guest is asked to shut down; the next start boots it again.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
options?LifecycleOptionswait: false resolves once the request is accepted; timeoutMs (default 5 minutes) and signal control the wait.

Returns

Promise<BoxInfo>

The Box's record: once stopped, or as accepted with wait: false.

Throws

CubicleApiError with code conflict while a snapshot or restore of the Box is in progress, or forbidden without a grant on the Box or the owner or admin role in its organization.

Throws

CubicleBoxError when another request changes its desired state.

Throws

CubicleTimeoutError when it is not stopped in time.

Example

await cubicle.boxes.stop("acme/job-1")

// Or only request it, and wait later.
await cubicle.boxes.stop("acme/job-1", { wait: false })
await cubicle.boxes.waitUntil("acme/job-1", "stopped")

waitUntil()

waitUntil(
   ref, 
   target, 
   options?
): Promise<BoxInfo>;

Polls until the Box is ready (SSH and exec usable), stopped or hibernated. Rejects with CubicleBoxError when it fails, is deleted, or another request changes its desired state.

It never changes the Box. Its desired state must already match target (running for ready), or it rejects with box_superseded at once.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
targetWaitTargetready, stopped or hibernated.
options?WaitOptionstimeoutMs (default 5 minutes) and signal.

Returns

Promise<BoxInfo>

The Box's record once it reached target.

Throws

CubicleBoxError with code box_failed, restart_required, hibernation_failed or box_superseded.

Throws

CubicleTimeoutError when the target is not reached in time; last is the Box's latest record.

Throws

CubicleApiError with code not_found when the Box does not exist.

Example

await cubicle.boxes.start("acme/job-1", { wait: false })
const info = await cubicle.boxes.waitUntil("acme/job-1", "ready", { timeoutMs: 600_000 })

waitUntilReady()

waitUntilReady(ref, options?): Promise<BoxInfo>;

Same as waitUntil(ref, "ready", options): polls until exec and new SSH connections can be used.

Parameters

ParameterTypeDescription
refstringThe Box's ID, ORG/NAME or bare NAME.
options?WaitOptionstimeoutMs (default 5 minutes) and signal.

Returns

Promise<BoxInfo>

On this page