Sandboxes
Create a short-lived, isolated sandbox that runs one command, follow its state and read its output and record.
Last updated
On this page
Description and operation
General
A sandbox is a short-lived, isolated machine for one run of code that you wrote. It has a file system, a toolchain and a network. It has no effect on other workspaces.
A sandbox runs one main process. You give the command at creation. The sandbox ends when that process exits. Other processes can run inside the sandbox, but the sandbox waits only for the main one.
A sandbox runs once. When it ends, its files are gone and it cannot start again. To run again, create a new sandbox.
| Way to run | Use | Command |
|---|---|---|
| Create | Start a sandbox, keep its id and read the output and the exit code later. See Create a sandbox with a command. | kloudlite sandboxes create -- cmd |
| Run | Run one command and read its output and exit code in one step. The sandbox ends with the command. See Run a command. | kloudlite sandboxes run -- cmd |
| Run with a terminal | Type to the process. Add -it. See Open a shell. | kloudlite sandboxes run -it -- sh |
Each sandbox has its own kernel, file system and network stack, with allocated vCPU, memory and disk. A sandbox belongs to you or to a team that you are an active member of. Nobody else sees it. The platform gives it an id that starts with sbx-.
| Part | Description |
|---|---|
| Main process | The command that you give at creation. See Commands and Shell. |
| Disk | /home/kl. It is removed when the sandbox ends. The home is not kept. |
| Working directory | ~/workspace. The main process starts here. |
| Packages | The toolchain, from nixpkgs. Give name or name@version at creation. |
| Output | The live output of the main process, then its last 256 KiB. See Read the output. |
| Network | Internet access, or none. The network none gives no DNS and no internet. |
| Resources | 1 to 8 vCPU, 1 to 32 GB of memory, and the disk size that you give. |
Sandbox types
A sandbox is standalone or in a session. The type is set at creation and does not change.
| Aspect | Standalone | In a session |
|---|---|---|
| Created with | POST /v1/sandboxes | POST /v1/sessions/{id}/sandboxes. See Sandboxes. |
| Ended by | The main process, you, or the time limit | The main process, you, the time limit, or the end of its session |
| Reaches an environment | No | The session's environment. It is the only way. See Sandboxes. |
session field | Empty | The session's name |
Sources
A sandbox starts from one of three sources. The source decides what is in the sandbox when it starts.
| Source | How you give it | What the sandbox has |
|---|---|---|
| The platform | No source field | The base tools and the packages that you give. |
| An image | image | The tools of that container image. |
| A copy | from_workspace or from_snapshot (not both) | The files of the workspace at the time of the request, or of the snapshot. |
Creation parameters
| Parameter | Required | Description |
|---|---|---|
cmd | Yes | The main process: the program, then its arguments. 256 arguments and 256 KiB at most. The sandbox ends when it exits. |
tty | No | Run cmd on a terminal. The default is false. |
stdin | No | Keep the input open so that you can attach to the process. The default is false. |
timeout_s | No | The hard lifetime, 10 to 86400 seconds. The default is 300. |
network | No | internet (default) or none. |
cpu | No | vCPU cores, 1 to 8. The default is 1. |
memory_gb | No | Memory, 1 to 32 GB. The default is 2. |
disk_gb | No | Disk, 1 GB up to the platform ceiling. The default is 10. |
env | No | Variables, 64 at most, 32 KiB for each value. A value of ${{ secrets.NAME }} refers to a secret. In a team sandbox, your personal secret in the team comes first, then the secret of the team. |
packages | No | The packages to install: name or name@version. |
image, from_workspace, from_snapshot | No | The source. See Sources. Give one. |
team | No | A team that you belong to. The default is you. |
The variables belong to the main process. A variable name uses letters, digits and _, does not start with a digit, and is not HOME or KL_ followed by anything.
States
A sandbox never stops and starts again. A create call returns at once with the phase pending. A fast command can end without the sandbox being running.
phase | Meaning |
|---|---|
pending | The platform recorded the sandbox. |
starting | The platform starts the sandbox. |
running | The main process runs. The time limit counts from here. |
terminated | The sandbox ended. The field reason gives the cause. |
reason | Meaning |
|---|---|
Terminated | You ended the sandbox. |
Timeout | It reached timeout_s. |
Exited | The main process exited. exit_code gives its code. |
Failed | The sandbox or the create failed. message gives the cause. |
Unplaceable | The platform found no place to run it. |
SourceGone | The workspace or snapshot it started from no longer exists. |
Lost | The platform stopped running it. |
EnvironmentGone | The environment of its session was deleted. |
The record also has exit_code, message (the cause of a failure), the times, the size and the source.
Lifecycle
- Create. The call returns at once. The phase is
pending, thenstarting, thenrunning. - Run. The hard lifetime counts from
runningand always applies. A sandbox has no idle limit. - In a session. A sandbox created through a session is controlled through that session. It ends when the session ends. See Sandboxes.
- End. The main process exits, you end the sandbox, or the time limit ends it. Its processes end and its files are gone.
- Record. The record of an ended sandbox stays for 90 days. It shows the phase, the reason, the exit code, the output, the times, the size and the source. A delete removes the record.
Quota and limits
A running sandbox counts its CPU, memory and disk against the owner's quota. An ended sandbox counts nothing. The sandboxes dimension of the quota limits how many sandboxes run at the same time.
| Item | Limit |
|---|---|
| Hard lifetime | 10 to 86400 seconds. |
| Command | 256 arguments and 256 KiB. |
| Output kept | The last 256 KiB. |
| CPU cores | 1 to 8. |
| Memory | 1 to 32 GB. |
| Disk | 1 GB up to the platform ceiling. |
| Variables | 64, each value up to 32 KiB. |
| Record | 90 days after the end. |
Tasks
Create a sandbox with a command
Reason for the task: Start an isolated machine that runs one command and ends with it.
Job set-up
- Access: you.
- References:
POST /v1/sandboxes.
The files of a sandbox are lost when it ends. Read the files that you need before the end.
Procedure
Create the sandbox with the command. The call returns at once.
from kloudlite import Kloudlitekl = Kloudlite()sb = kl.sandboxes.create(cmd=["python3", "main.py"], packages=["python3"], timeout_s=600)import { Kloudlite } from "./index.ts";const kl = new Kloudlite();const sb = await kl.sandboxes.create({ cmd: ["python3", "main.py"], packages: ["python3"], timeoutS: 600 });kl := kloudlite.New(kloudlite.Options{})sb, err := kl.Sandboxes.Create(kloudlite.CreateSandbox{Cmd: []string{"python3", "main.py"}, Packages: []string{"python3"}, Timeout: 600 * time.Second})if err != nil { log.Fatal(err)}require_relative "kloudlite"kl = Kloudlite::Client.newsb = kl.sandboxes.create(cmd: ["python3", "main.py"], packages: ["python3"], timeout_s: 600)var kl = new Kloudlite();var sb = kl.sandboxes().create(new Kloudlite.CreateSandbox().cmd(List.of("python3", "main.py")).packages("python3").timeout(Duration.ofSeconds(600)));kloudlite sandboxes create --package python3 --timeout-s 600 -- python3 main.py
Close-out
- Show the status as in task 002. Make sure that
phaseispending,starting,runningorterminated.
Show the status of a sandbox
Reason for the task: Read the phase of a sandbox and, when it ended, the reason and the exit code.
Job set-up
- Access: you.
- References:
GET /v1/sandboxes/{id}.
Procedure
Read the record of the sandbox. The record shows the phase, the reason, the exit code and the times.
print(kl.sandboxes.get(sandbox="sbx-3c4d5e6f7a8b9c0d").doc)console.log((await kl.sandboxes.get({ sandbox: "sbx-3c4d5e6f7a8b9c0d" })).doc);got, err := kl.Sandboxes.Get("sbx-3c4d5e6f7a8b9c0d")if err != nil { log.Fatal(err)}fmt.Printf("%+v\n", got.SandboxDoc)pp kl.sandboxes.get(sandbox: "sbx-3c4d5e6f7a8b9c0d").docSystem.out.println(kl.sandboxes().get("sbx-3c4d5e6f7a8b9c0d").json());kloudlite sandboxes get sbx-3c4d5e6f7a8b9c0dWait until the sandbox is
running. The call fails with the reason when the sandbox ends first.sb.wait_running(timeout_s=120)await sb.waitRunning({ timeoutS: 120 });if err := sb.WaitRunning(120 * time.Second); err != nil { log.Fatal(err)}sb.wait_running(timeout_s: 120)sb.waitRunning(Duration.ofSeconds(120));kloudlite sandboxes wait-running sbx-3c4d5e6f7a8b9c0d --timeout-s 120
Close-out
- Make sure that the phase is
running, orterminatedwith areason. Make sure thatexit_codeis set when the reason isExited.
End a sandbox
Reason for the task: Stop a sandbox before its command exits or its time limit, and release its resources.
Job set-up
- Access: you.
- Conditions: you have the handle
sb. Usesandboxes.getwith the id to get it. - References:
POST /v1/sandboxes/{id}/terminate,DELETE /v1/sandboxes/{id}.
A delete removes the record of the sandbox. A sandbox that still runs ends with it.
Procedure
Stop the sandbox. The call is safe to repeat.
sb.terminate()await sb.terminate();if err := sb.Terminate(); err != nil { log.Fatal(err)}sb.terminatesb.terminate();kloudlite sandboxes terminate sbx-3c4d5e6f7a8b9c0dWait until the sandbox ends. The call returns the exit code, or no code when the process did not exit by itself.
code = sb.wait()const code = await sb.wait();code, err := sb.Wait(0)if err != nil { log.Fatal(err)}code = sb.waitint code = sb.waitFor(null);kloudlite sandboxes wait sbx-3c4d5e6f7a8b9c0dDelete the record if you do not need it.
sb.delete()await sb.delete();if err := sb.Delete(); err != nil { log.Fatal(err)}sb.deletesb.delete();kloudlite sandboxes delete sbx-3c4d5e6f7a8b9c0d
Close-out
- Make sure that
reasonisTerminated, orExitedwhen the command ended first.
Show the run records
Reason for the task: Find the sandboxes of an owner and read why each one ended.
Job set-up
- Access: you.
- References:
GET /v1/sandboxes,GET /v1/sandboxes/{id}.
Procedure
Show the sandboxes, newest first. Give a team to show only its sandboxes.
for s in kl.sandboxes.list(): print(s.id, s.phase, s.reason)for (const s of await kl.sandboxes.list()) { console.log(s.id, s.phase, s.reason);}sandboxes, err := kl.Sandboxes.List("")if err != nil { log.Fatal(err)}for _, s := range sandboxes { fmt.Println(s.ID, s.Phase, s.Reason)}kl.sandboxes.list.each do |s| puts "#{s.id} #{s.phase} #{s.reason}"endfor (var s : kl.sandboxes().list(null)) { System.out.println(s.id() + " " + s.phase() + " " + s.reason());}kloudlite sandboxes list
Close-out
- Make sure that each ended sandbox shows the phase
terminated, a reason and its times.
Read the output and the exit code
Reason for the task: Read what the command printed and how it ended.
Job set-up
- Access: you.
- Conditions: you have the handle
sb. Usesandboxes.getwith the id to get it. - References:
GET /v1/sandboxes/{id}/logs,POST /v1/sandboxes/{id}/wait.
After the end, the platform keeps the last 256 KiB of the output with the record for 90 days.
Procedure
Wait for the command to exit. The call returns the exit code.
code = sb.wait()const code = await sb.wait();code, err := sb.Wait(0)if err != nil { log.Fatal(err)}code = sb.waitint code = sb.waitFor(null);kloudlite sandboxes wait sbx-3c4d5e6f7a8b9c0dRead the output. Give
followto hold the call until the command ends.print(sb.logs())console.log(await sb.logs());out, err := sb.Logs(false)if err != nil { log.Fatal(err)}fmt.Print(out)puts sb.logsSystem.out.print(sb.logs(false));kloudlite sandboxes logs sbx-3c4d5e6f7a8b9c0d
Close-out
- Make sure that the exit code is
0and the output is the one that you expect.
Troubleshooting
| Symptom | Possible cause | Corrective action |
|---|---|---|
409 with sandboxes: … in use; request more under Quota (or cpu, memoryGb, diskGb) | You use the full quota. | End a sandbox that you do not need, or request more quota. |
409 with sandbox sbx-… has no output yet (starting) | The sandbox has not started. | Wait, then read the output again. |
409 with sandbox sbx-… has terminated (Timeout) | The sandbox ended. The text gives the reason. | Create a new sandbox with a larger timeout_s. |
404 with not found | The sandbox does not exist, or is not yours. | Check the id in the run records. |
422 with timeout_secs must be between 10 and 86400 | The time limit is out of range. | Set timeout_s from 10 to 86400. |
422 for cmd | The command is empty or too long. | Give the program and at most 256 arguments. |
422 with from_workspace and from_snapshot are exclusive | The create call gives two sources. | Give one of them. |
422 with env: HOME is set by the platform | A variable name is not valid. | Use a different name. |
422 with create a session's sandbox with POST /v1/sessions/{id}/sandboxes | The create body has session. | Remove session. To create a sandbox in a session, see Sandboxes. |
409 with sandbox sbx-… is managed by session dev; use the session | The sandbox belongs to a session, and the call ends or deletes it directly. | End the session, or wait for the time limit. See Sandboxes. |
phase is terminated and reason is Unplaceable | The platform found no place to run the sandbox. | Create the sandbox again with less cpu or memory_gb, or wait. |
phase is terminated and reason is SourceGone | The workspace or snapshot that the sandbox copies was deleted. | Create the sandbox again from another source. |
phase is terminated and reason is Exited with an exit_code other than 0 | The command failed. | Read the output. |
phase is terminated and reason is Failed or Lost | The sandbox or the create failed, or the platform stopped it. | Read message in the record. Create a new sandbox. |
403 with your access to {team} is paused | A team admin paused your access. | Ask a team admin to restore it. |