Capabilities
Ask a server which lifecycle verbs it supports before you call one. A verb the provider lacks fails with an error, so code that pauses or forks can check first and take another path. On a Sysbox server:
shard capabilitiesCAPABILITY SUPPORTEDcreate truestart truestop trueremove truepause falseresume falsefork falsesnapshot trueport trueswap falseimport { Shard } from "useshards";
const shard = new Shard();try { const caps = await shard.capabilities(); console.log(caps.pause, caps.fork); // false false} finally { shard.close();}from useshards import Shard
with Shard() as shard: caps = shard.capabilities() print(caps.pause, caps.fork) # False FalseThe SDK examples connect to the server that SHARD_REMOTE names, with the API key in SHARD_API_KEY.
The answer lists all nine verbs and swap, each true or false. It comes from the provider of the daemon, so it is the same for every sandbox on that server. Token scopes and sandbox states never change it.
The verbs of each provider
Section titled “The verbs of each provider”One daemon runs one provider for every sandbox on its host. Every provider supports the same six of the nine verbs. Pause, resume and fork are optional:
| Verb | gVisor | Sysbox | runc | vz | Firecracker |
|---|---|---|---|---|---|
create, start, stop, remove, snapshot, port |
yes | yes | yes | yes | yes |
pause |
yes | no | no | Apple silicon with macOS 14 or later | yes |
resume |
yes | no | no | Apple silicon with macOS 14 or later | yes |
fork |
yes | no | no | Apple silicon with macOS 14 or later | yes |
swap says whether --swap can give a sandbox a swap file: yes on vz and Firecracker, no on the rest. snapshot is shard snapshot create, which copies the files of a stopped sandbox. fork copies a sandbox while it runs. port is shard port add, which forwards a host port into a sandbox. Every provider also supports exec, logs and inspect, which the answer does not list.
The API
Section titled “The API”GET /v0/capabilities answers the same ten fields:
curl --unix-socket /var/lib/shard/shard.sock http://localhost/v0/capabilities{ "create": true, "start": true, "stop": true, "remove": true, "pause": false, "resume": false, "fork": false, "snapshot": true, "port": true, "swap": false}Through shard serve, any valid token can read it, whatever its scopes. shard capabilities --format json prints the same object.
A verb the provider lacks
Section titled “A verb the provider lacks”shard refuses the verb. It never falls back to a weaker verb, such as a stop in place of a pause. The refusal comes before the daemon changes anything, so the sandbox keeps its state:
shard pause quiet-heron-3f0a# shard: provider sysbox does not support pause on this host; use a server that supports pauseimport { Shard, UnsupportedError } from "useshards";
const shard = new Shard();try { const sandbox = await shard.get("quiet-heron-3f0a"); await sandbox.pause();} catch (err) { if (!(err instanceof UnsupportedError)) throw err; console.log(err.status, err.code); // 409 unsupported} finally { shard.close();}from useshards import Shard, UnsupportedError
with Shard() as shard: sandbox = shard.get("quiet-heron-3f0a") try: sandbox.pause() except UnsupportedError as err: print(err.status, err.code) # 409 unsupportedThe API answers 409 with the code unsupported:
{"error":{"code":"unsupported","message":"provider sysbox does not support pause on this host; use a server that supports pause"}}The message names the provider and the verb. Errors and exit codes lists every code.
The provider of a host
Section titled “The provider of a host”shard daemon status names the provider of the running daemon. shard daemon --provider <name> picks one. Without the flag, the daemon picks one from its root, then from the host:
| The root and the host | The provider |
|---|---|
| A root that holds sandbox records | The provider that made them |
| A root whose every record cannot be read | None. The daemon refuses to start until --provider names one |
A root with no records, beside a <root>.xfs image |
firecracker |
A root with no records, on Linux, where /dev/kvm opens |
firecracker |
A root with no records, on Linux, with no /dev/kvm or one that does not open |
gvisor |
| A root with no records, on macOS | vz |
On a root with no records, the daemon never picks sysbox or runc: Sysbox is single-tenant, and runc runs a sandbox straight on the host kernel. To use one of them, name it with --provider. shard info prints the provider that a new daemon would pick on this host, and the reason. It runs on the daemon host only.
A root keeps the provider that made its records, because no other provider can read them. The daemon refuses a --provider that names another one before it touches the root, and the error names both providers.