Processes
Run, spawn and attach to processes in a sandbox through cua-spacesd.
Run a command to completion with run or sh, or spawn a SpacesdProcess to stream its output and write its input.
Python programs usually use the high-level API instead: sb.shell, sb.terminal.
Run processes#
Methods of SpacesdClient.
SpacesdClient.run#
Runs a command to completion.
async def run(self, command: SpacesdCommand) -> ProcessOutput| Parameter | Type | Default |
|---|---|---|
command | SpacesdCommand | required |
Returns ProcessOutput · Async · Raises CuaError
Example
import asyncio
import cua
async def main():
guest = await cua.embedded().spacesd(URL, TOKEN) # or: await sandbox.spacesd(None)
out = await guest.run(cua.SpacesdCommand(program="echo", args=["hello"]))
print([out.exit.success, out.stdout])
# [True, b'hello\n']
asyncio.run(main())SpacesdClient.sh#
Runs line with /bin/sh -c to completion.
async def sh(self, line: str, timeout_ms: Optional[int]) -> ProcessOutput| Parameter | Type | Default |
|---|---|---|
line | String | required |
timeout_ms | Option<u32> | required |
Returns ProcessOutput · Async · Raises CuaError
SpacesdClient.spawn#
Starts a command and returns its handle.
async def spawn(self, command: SpacesdCommand) -> SpacesdProcess| Parameter | Type | Default |
|---|---|---|
command | SpacesdCommand | required |
Returns SpacesdProcess · Async · Raises CuaError
Example
import asyncio
import cua
async def main():
guest = await cua.embedded().spacesd(URL, TOKEN)
proc = await guest.spawn(cua.SpacesdCommand(program="cat", args=[], stdin=True))
await proc.write_stdin(b"xyz")
await proc.close_stdin()
print([(await proc.wait()).stdout])
# [b'xyz']
asyncio.run(main())SpacesdClient.attach#
Attaches to a running process by pid or tag.
async def attach(self, pid: Optional[int], tag: Optional[str], replay: ReplayMode) -> SpacesdProcess| Parameter | Type | Default |
|---|---|---|
pid | Option<u32> | required |
tag | Option<String> | required |
replay | ReplayMode | required |
Returns SpacesdProcess · Async · Raises CuaError
SpacesdClient.list_processes#
Guest processes as proto3 JSON ([ProcessInfo]).
async def list_processes(self, include_exited: bool) -> str| Parameter | Type | Default |
|---|---|---|
include_exited | bool | required |
Returns String · Async · Raises CuaError
SpacesdProcess#
A guest process, from spawn or attach.
Returned by SpacesdClient.attach, SpacesdClient.spawn.
| Method | Description |
|---|---|
close_stdin | Closes stdin. |
detach | Stops receiving output without affecting the process. |
kill | SIGKILL to the process and its process group (what it started), including a command run as another user through sudo. |
next_event | Next output chunk or the exit; None after the exit was returned. |
resize | Resizes the PTY. |
signal | Sends a signal by name (term, kill, SIGINT, ...). |
wait | Collects the remaining output until exit. |
write_pty | Writes PTY keystrokes. |
write_stdin | Writes stdin (PTY input for PTY processes), exactly once across retries. |
| Accessor | Returns | Description |
|---|---|---|
pid() | u32 | Guest pid. |
tag() | Option<String> | Tag, when set. |
SpacesdProcess.close_stdin#
Closes stdin.
async def close_stdin(self) -> NoneAsync · Raises CuaError
SpacesdProcess.detach#
Stops receiving output without affecting the process. A pending
next_event returns None at once.
async def detach(self) -> NoneAsync
SpacesdProcess.kill#
SIGKILL to the process and its process group (what it started),
including a command run as another user through sudo.
async def kill(self) -> NoneAsync · Raises CuaError
SpacesdProcess.next_event#
Next output chunk or the exit; None after the exit was returned.
Reconnects transparently from the last seen offset.
async def next_event(self) -> Optional[ProcessEvent]Returns Option<ProcessEvent> · Async · Raises CuaError
SpacesdProcess.resize#
Resizes the PTY.
async def resize(self, cols: int, rows: int) -> None| Parameter | Type | Default |
|---|---|---|
cols | u32 | required |
rows | u32 | required |
Async · Raises CuaError
SpacesdProcess.signal#
Sends a signal by name (term, kill, SIGINT, ...). With
process_group, to the process's whole group (everything it started),
as a terminal's Ctrl-C does; by default to the process alone.
async def signal(self, signal: str, process_group: bool = False) -> None| Parameter | Type | Default |
|---|---|---|
signal | String | required |
process_group | bool | false |
Async · Raises CuaError
SpacesdProcess.wait#
Collects the remaining output until exit.
async def wait(self) -> ProcessOutputReturns ProcessOutput · Async · Raises CuaError
SpacesdProcess.write_pty#
Writes PTY keystrokes.
async def write_pty(self, data: bytes) -> None| Parameter | Type | Default |
|---|---|---|
data | Vec<u8> | required |
Async · Raises CuaError
SpacesdProcess.write_stdin#
Writes stdin (PTY input for PTY processes), exactly once across retries.
async def write_stdin(self, data: bytes) -> None| Parameter | Type | Default |
|---|---|---|
data | Vec<u8> | required |
Async · Raises CuaError
SpacesdCommand record#
A command to run in the guest.
| Field | Type | Default | Description |
|---|---|---|---|
program | String | Program (absolute path or PATH lookup). | |
args | Vec<String> | [] | Arguments. |
env | HashMap<String, String> | [:] | Extra environment. |
cwd | Option<String> | None | Working directory. |
user | Option<String> | None | Run as this user. |
timeout_ms / timeoutMs | Option<u32> | None | Kill after this long. |
tag | Option<String> | None | Tag for reattaching (attach(tag=…)). |
stdin | bool | false | Keep stdin open for write_stdin. |
pty | Option<PtySize> | None | Run in a PTY of this size. |
request_id / requestId | Option<String> | None | Idempotency key: a later start with the same key reattaches to the running process or replays its recorded outcome instead of running the command again (the guest's exec ledger; see GetExecRecord). |
epoch | Option<u64> | None | Fencing epoch: a start with an epoch lower than the Space's current one is refused; a higher one advances it. None is unfenced. |
scrollback_bytes / scrollbackBytes | Option<u64> | None | Size of the guest's output scrollback ring for this process, in bytes. The ring never blocks the process: a reader that falls more than this far behind loses the evicted bytes (visible as an offset gap). None uses the server default (8 MiB); the server clamps larger requests to its maximum (512 MiB) rather than failing. The ring is allocated up to this size as output arrives, so the cost is bounded by the output actually produced. |
kill_on_disconnect / killOnDisconnect | bool | false | Kill the process (term, then kill) when this client's connection to cua-spacesd ends before the process does, including when the client process dies. Off by default: processes are detached and can be reattached by tag. |
ProcessOutput record#
Collected output of a finished process.
Returned by Sandbox.guest_sh, SpacesdClient.run, SpacesdClient.sh, SpacesdProcess.wait.
| Field | Type | Default | Description |
|---|---|---|---|
exit | ExitInfo | Exit. | |
stdout | Vec<u8> | stdout bytes. | |
stderr | Vec<u8> | stderr bytes. | |
pty | Vec<u8> | PTY bytes. |
ExitInfo record#
How a process ended.
| Field | Type | Default | Description |
|---|---|---|---|
code | Option<i32> | Exit code for a normal exit. | |
signal | Option<String> | Terminating signal (kill, term, ...). | |
signal_number / signalNumber | Option<i32> | None | Raw number of the terminating signal on the guest's OS, set for every signal death, also for those signal has no name for (SIGSEGV, SIGABRT, SIGPIPE, ...). |
signal_name / signalName | Option<String> | None | Conventional name of the terminating signal without SIG, in upper case ("SEGV", "ABRT"); independent of the guest's OS. |
timed_out / timedOut | bool | Stopped by its timeout. | |
error | Option<String> | Supervisor error (for example "executable not found"). | |
success | bool | code == 0. |
ProcessEvent record#
One output chunk or the exit.
Returned by SpacesdProcess.next_event.
| Field | Type | Default | Description |
|---|---|---|---|
kind | ProcessEventKind | Kind. | |
offset | u64 | Combined-output offset of the first byte. | |
data | Vec<u8> | Bytes (empty for Exit). | |
exit | Option<ExitInfo> | Exit (only for Exit). |
ProcessEventKind enum#
Kind of a process event.
ProcessEventKind.STDOUT
ProcessEventKind.STDERR
ProcessEventKind.PTY
ProcessEventKind.EXIT| Variant | Description |
|---|---|
Stdout | stdout bytes. |
Stderr | stderr bytes. |
Pty | PTY bytes. |
Exit | The process ended (always last). |
PtySize record#
A PTY size.
| Field | Type | Default | Description |
|---|---|---|---|
cols | u32 | Columns. | |
rows | u32 | Rows. |
ReplayMode enum#
Scrollback replay when attaching.
ReplayMode.NONE()
ReplayMode.ALL()
ReplayMode.LAST_BYTES(n: int)
ReplayMode.FROM_OFFSET(offset: int)| Variant | Description |
|---|---|
None | Live output only. |
All | Everything retained. |
LastBytes | The last n bytes. Fields: n: u64 |
FromOffset | From this combined-output offset. Fields: offset: u64 |