e0e362d700
SDK Tests / SDK CI (push) Blocked by required conditions
SDK Tests / changes (push) Successful in 2m29s
Real E2E Tests / changes (push) Successful in 2m29s
SDK Tests / Python SDK Tests (sandbox) (push) Waiting to run
SDK Tests / CLI Quality (push) Waiting to run
SDK Tests / CLI Tests (push) Waiting to run
SDK Tests / Python SDK Quality (code-interpreter) (push) Waiting to run
SDK Tests / Python SDK Quality (sandbox) (push) Waiting to run
SDK Tests / Python SDK Tests (code-interpreter) (push) Waiting to run
SDK Tests / JavaScript SDK Quality And Tests (code-interpreter) (push) Waiting to run
SDK Tests / JavaScript SDK Quality And Tests (sandbox) (push) Waiting to run
SDK Tests / Kotlin SDK Quality And Tests (sandbox) (push) Waiting to run
SDK Tests / Kotlin SDK Quality And Tests (code-interpreter) (push) Waiting to run
SDK Tests / C# SDK Quality And Tests (code-interpreter) (push) Waiting to run
SDK Tests / C# SDK Quality And Tests (sandbox) (push) Waiting to run
SDK Tests / Go SDK Quality And Tests (push) Waiting to run
Deploy Docs Pages / build (push) Has been cancelled
Deploy Docs Pages / deploy (push) Has been cancelled
Real E2E Tests / JavaScript E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Python E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Java E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / C# E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Go E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Real E2E CI (push) Has been cancelled
172 lines
5.7 KiB
Markdown
172 lines
5.7 KiB
Markdown
---
|
|
title: execd
|
|
description: The in-sandbox execution daemon providing HTTP APIs for code execution, shell commands, filesystem operations, PTY sessions, and metrics.
|
|
---
|
|
|
|
# execd - OpenSandbox Execution Daemon
|
|
|
|
`execd` is the runtime daemon used inside OpenSandbox sandboxes.
|
|
|
|
It is built on Gin and exposes HTTP APIs for code execution, shell commands, filesystem operations, PTY sessions, and metrics.
|
|
|
|
## Quick Start
|
|
|
|
### 1) Build
|
|
|
|
```bash
|
|
cd components/execd
|
|
make build
|
|
```
|
|
|
|
### 2) Start Jupyter Server
|
|
|
|
```bash
|
|
./tests/jupyter.sh
|
|
```
|
|
|
|
### 3) Run execd
|
|
|
|
```bash
|
|
./bin/execd \
|
|
--jupyter-host=http://127.0.0.1:54321 \
|
|
--jupyter-token=your-jupyter-token \
|
|
--port=44772
|
|
```
|
|
|
|
### 4) Verify
|
|
|
|
```bash
|
|
curl -v http://localhost:44772/ping
|
|
```
|
|
|
|
## API
|
|
|
|
- OpenAPI spec: [execd-api.yaml](/api/)
|
|
- Common capability groups:
|
|
- Code execution (`/code`, SSE stream)
|
|
- Session and command execution (`/session`, `/command`)
|
|
- Filesystem operations (`/files`, `/directories`)
|
|
- Isolated sessions (`/v1/isolated/session`, bubblewrap namespaces)
|
|
- PTY over WebSocket (`/pty`)
|
|
- Local metrics endpoints (`/metrics`, `/metrics/watch`)
|
|
|
|
## Isolated Sessions
|
|
|
|
Isolated sessions run a bash process inside a per-execution
|
|
[bubblewrap](https://github.com/containers/bubblewrap) (`bwrap`) namespace,
|
|
created via `POST /v1/isolated/session`. Beyond the workspace, callers can
|
|
expose additional host paths into the namespace.
|
|
|
|
### Bind mounts
|
|
|
|
Two request fields control extra host paths:
|
|
|
|
- `extra_writable`: a list of paths bind-mounted read-write at the same path
|
|
inside the namespace (`source == destination`).
|
|
- `binds`: explicit `source` → `dest` mappings, each optionally read-only.
|
|
- `source` (required): host path to bind. It must **already exist** and is
|
|
resolved (symlinks followed) before use.
|
|
- `dest`: mount destination inside the namespace; defaults to `source` when
|
|
omitted. It must be an **existing** mount point — `bwrap` cannot create a
|
|
destination under the read-only root, so create the directory first.
|
|
- `readonly` (default `false`): mount read-only (`--ro-bind`) when `true`,
|
|
read-write (`--bind`) otherwise.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"workspace": { "path": "/workspace", "mode": "rw" },
|
|
"binds": [
|
|
{ "source": "/data/in", "dest": "/mnt/in", "readonly": true },
|
|
{ "source": "/data/out", "dest": "/mnt/out" }
|
|
]
|
|
}
|
|
```
|
|
|
|
### Writable allowlist
|
|
|
|
The source path of every `extra_writable` entry and every `binds` entry must
|
|
fall within the `allowed_writable` allowlist (see the isolation config file
|
|
below). The allowlist is enforced against the fully symlink-resolved real
|
|
path, so a symlink cannot redirect a bind outside the allowlist. An empty
|
|
allowlist rejects all `extra_writable`/`binds` requests.
|
|
|
|
The built-in default allowlist is `/workspace`, `/mnt`, `/media`, `/data`
|
|
(subpaths included). Set `allowed_writable` in the isolation config to
|
|
override it.
|
|
|
|
## Configuration
|
|
|
|
### CLI Flags
|
|
|
|
| Flag | Default | Description |
|
|
|---|---|---|
|
|
| `--jupyter-host` | `""` | Jupyter server URL reachable by execd. |
|
|
| `--jupyter-token` | `""` | Jupyter token for HTTP/WebSocket auth. |
|
|
| `--port` | `44772` | HTTP listen port. |
|
|
| `--log-level` | `6` | Log level (0=Emergency, 7=Debug). |
|
|
| `--access-token` | `""` | Optional shared API access token. |
|
|
| `--graceful-shutdown-timeout` | `1s` | SSE tail-drain wait window before closing. |
|
|
| `--jupyter-idle-poll-interval` | `100ms` | Poll interval after Jupyter reports idle. |
|
|
| `--isolation-config` | `""` | Path to the isolation TOML config (see below). |
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Description |
|
|
|---|---|
|
|
| `JUPYTER_HOST` | Same as `--jupyter-host` (overridden by explicit flag). |
|
|
| `JUPYTER_TOKEN` | Same as `--jupyter-token` (overridden by explicit flag). |
|
|
| `EXECD_ACCESS_TOKEN` | Same as `--access-token` (overridden by explicit flag). |
|
|
| `EXECD_API_GRACE_SHUTDOWN` | Same as `--graceful-shutdown-timeout`. |
|
|
| `EXECD_JUPYTER_IDLE_POLL_INTERVAL` | Same as `--jupyter-idle-poll-interval`. |
|
|
| `EXECD_ISOLATION_CONFIG` | Same as `--isolation-config`. |
|
|
| `EXECD_CLONE3_COMPAT` | Linux clone3 compatibility switch (see below). |
|
|
| `EXECD_LOG_FILE` | Optional log output file path; default is stdout. |
|
|
| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | Preferred OTLP metrics endpoint. |
|
|
| `OTEL_EXPORTER_OTLP_ENDPOINT` | Fallback OTLP endpoint when metrics-specific endpoint is unset. |
|
|
| `OPENSANDBOX_ID` | Optional `sandbox_id` metric/resource attribute. |
|
|
| `OPENSANDBOX_EXECD_METRICS_EXTRA_ATTRS` | Optional extra metric attrs (`k=v,k2=v2`). |
|
|
|
|
### Isolation Config File
|
|
|
|
Isolated sessions read an optional TOML file given by `--isolation-config`
|
|
(or `EXECD_ISOLATION_CONFIG`). All fields are optional; omitted fields use
|
|
built-in defaults.
|
|
|
|
```toml
|
|
# Parent directory for per-session overlay upper directories.
|
|
upper_root = "/var/lib/execd/isolation"
|
|
|
|
# Host paths callers may request via extra_writable / binds.
|
|
# Enforced against the fully symlink-resolved real path; subpaths are allowed.
|
|
# Default: ["/workspace", "/mnt", "/media", "/data"]. Empty = reject all.
|
|
allowed_writable = ["/workspace", "/mnt", "/media", "/data"]
|
|
```
|
|
|
|
## Observability
|
|
|
|
### OpenTelemetry Metrics
|
|
|
|
OTLP metrics export is enabled when either endpoint is set:
|
|
|
|
- `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`
|
|
- `OTEL_EXPORTER_OTLP_ENDPOINT`
|
|
|
|
### Local Metrics Endpoints
|
|
|
|
- `GET /metrics`: point-in-time host metrics snapshot
|
|
- `GET /metrics/watch`: SSE stream (1s cadence)
|
|
|
|
## Linux clone3 Compatibility
|
|
|
|
Some sandbox environments fail on `clone3(2)`.
|
|
Set `EXECD_CLONE3_COMPAT` in sandbox env to force fallback behavior:
|
|
|
|
- `1` / `true` / `yes` / `on`: enable seccomp fallback
|
|
- `reexec`: enable fallback and re-exec binary
|
|
|
|
## License
|
|
|
|
`execd` is part of OpenSandbox. See the [LICENSE](https://github.com/opensandbox-group/OpenSandbox/blob/main/LICENSE).
|