Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion sdk/go/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# cubesandbox Go SDK

Go SDK for [CubeSandbox](https://github.com/TencentCloud/CubeSandbox). It matches the current Python SDK surface: sandbox lifecycle, code execution, commands, filesystem operations (read, write, list, stat, exists, remove, rename, mkdir, watch), snapshots, clone, rollback, and L7 egress policy.
Go SDK for [CubeSandbox](https://github.com/TencentCloud/CubeSandbox). It matches the current Python SDK surface: sandbox lifecycle, code execution, commands, PTY (interactive terminal), filesystem operations (read, write, list, stat, exists, remove, rename, mkdir, watch), snapshots, clone, rollback, and L7 egress policy.

## Install

Expand Down Expand Up @@ -71,6 +71,61 @@ fmt.Println(result.Stdout, result.Stderr, result.ExitCode)

`Commands.Run` starts `/bin/bash -l -c <command>` through envd's `process.Process/Start` API and returns stdout, stderr, and the `EndEvent` exit code. Callers are still responsible for treating untrusted shell input carefully.

## PTY (interactive terminal)

`sb.Pty()` opens a real pseudo-terminal for interactive programs that need a TTY — shells/REPLs, full-screen tools (`vim`, `top`), or agent-driven terminals. It mirrors the Python/Node `sandbox.pty` surface.

```go
pty := sb.Pty()

// Start an interactive login shell (80x24). Optionally set opts.User / opts.Cwd.
handle, err := pty.Create(ctx, cubesandbox.PtySize{Rows: 24, Cols: 80}, cubesandbox.PtyCreateOptions{})
if err != nil {
panic(err)
}

// Drive it: send input, resize the window.
_ = handle.SendStdin(ctx, []byte("echo hi && stty size\n"))
_ = handle.Resize(ctx, cubesandbox.PtySize{Rows: 40, Cols: 120})

// Consume output with Wait's callback OR by ranging handle.Output() — not both,
// they share one stream. Wait blocks until the shell exits (or you call
// handle.Kill / handle.Disconnect) and returns the exit code.
code, err := handle.Wait(func(chunk []byte) {
os.Stdout.Write(chunk)
})
fmt.Println("pty exited with", code, err)
```

Reattach to a still-running PTY from elsewhere with `pty.Connect(ctx, pid, ...)`, or control one by PID without a handle:

```go
handle, _ := pty.Create(ctx, cubesandbox.PtySize{Rows: 24, Cols: 80}, cubesandbox.PtyCreateOptions{})
handle.Disconnect() // detach without killing; the shell keeps running

again, _ := pty.Connect(ctx, handle.PID(), cubesandbox.PtyConnectOptions{})
_ = pty.SendStdin(ctx, again.PID(), []byte("ls\n"))
killed, _ := pty.Kill(ctx, again.PID()) // false if the PID already exited
_ = killed
```

| Method | Description |
|---|---|
| `Pty.Create(ctx, size, opts)` | Start `/bin/bash -i -l` with a PTY; seeds `TERM`/`LANG`/`LC_ALL` (overridable via `opts.Envs`). Streaming `process.Process/Start`. |
| `Pty.Connect(ctx, pid, opts)` | Reattach to a running PTY. Streaming `process.Process/Connect`. |
| `Pty.Kill(ctx, pid)` | `SIGKILL` a PTY; returns `false` (not an error) if the PID was not found. |
| `Pty.SendStdin(ctx, pid, data)` | Write bytes to the PTY master (`SendInput`). |
| `Pty.Resize(ctx, pid, size)` | Resize the window (`Update`). |
| `handle.Output()` | Channel of raw output chunks; closed when the stream ends. |
| `handle.Wait(onData)` | Block until exit, return the exit code; surfaces envd errors (e.g. `signal: killed`). |
| `handle.Disconnect()` | Stop receiving output without killing the PTY. |
| `handle.PID()` / `ExitCode()` / `ErrorMessage()` | PTY process ID; exit code (returns `0, false` until known); and envd end error. |
| `handle.Kill` / `SendStdin` / `Resize` | Per-handle shortcuts that target this PTY's PID. |

Consume output via **either** `Output()` **or** `Wait(onData)`, not both — they share one stream.

`PtyCreateOptions.Timeout` / `PtyConnectOptions.Timeout` (default 60s, `<= 0` uses the default) is both sent to envd as `Connect-Timeout-Ms` and enforced client-side as an idle abort that resets on every received frame; on expiry `Wait` returns an "idle" timeout error.

## Files

```go
Expand Down
Loading
Loading