巴迪·沙盒SDK
TypeScript SDK 用于管理 Buddy sandboxs - 用于运行命令的孤立的Ubuntu环境.
安装
npm install @buddy-works/sandbox-sdk
使用量
import { Sandbox } from "@buddy-works/sandbox-sdk";
const identifier = "my-sandbox";
let sandbox: Sandbox;
try {
sandbox = await Sandbox.getByIdentifier(identifier);
} catch {
sandbox = await Sandbox.create({
identifier,
name: "My Sandbox",
os: "ubuntu:24.04",
});
}
await sandbox.start();
await sandbox.runCommand({
command: "ping -c 5 buddy.works",
});
await sandbox.stop();
设定所需的环境变量 :
export BUDDY_TOKEN="your-api-token"
export BUDDY_WORKSPACE="your-workspace"
export BUDDY_PROJECT="your-project"
export BUDDY_REGION="US" # Optional: US (default), EU, or AS
运行命令
exec() 运行一个命令,并在它完成后解析,并带有其退出代码和
输出 :
const result = await sandbox.exec({ command: "npm test" });
console.log(result.exit_code, result.stdout, result.stderr);
一个退出非零的命令仍然解决, 所以检查 exit_code。 。 。 .
runtime 选择翻译。 默认为 BASH,并且还要
JAVASCRIPT, (中文(简体) ), TYPESCRIPT 或者说 PYTHON数字 :
await sandbox.exec({ command: "print(1 + 1)", runtime: "PYTHON" });
请求在命令运行时保持开放, 60 后 API 失败 秒数。 不管做什么 命令都这样运行 沙盒里没有入口 命令历史,流无日志,无法终止.
使用 runCommand() 超过1分钟的输出
它到达,或者在呼叫返回后离开命令运行:
// streams to process.stdout as it runs, resolves once it finishes
const command = await sandbox.runCommand({ command: "npm test" });
console.log(command.data.status, command.data.exit_code);
// returns immediately, leaving the command running
const detached = await sandbox.runCommand({
command: "npm run build",
detached: true,
output: null,
});
for await (const line of detached.logs({ follow: true })) {
console.log(line);
}
const finished = await detached.wait(); // SUCCESSFUL, FAILED or CANCELLED
一个分离的命令仍然流到 process.stdout 默认时, 保留
将节点进程活到命令结束 - 通过 output: null 让它
快离开.
命令的日志中包含 stdout 和 stderr 互出,顺序为
命令写道: logs() 减小线条 output() 返回为一体
绳子。 使用 exec() 当你需要两个分开.
kill() 取消运行中的命令,并在命令停止后按
状态 CANCELLED 内 data,或者30秒后,如果它缓慢停止 - 那么
data.status 仍然是 INPROGRESS。 。 。 .
listCommands() 返回 sandbox 的命令历史, 首先是最新的 - API
保留最近的200个.
wait(), (中文(简体) ), logs() 财务报告和审定财务报表 output() 拿着 AbortSignal 停止等待,
命令的截止日期 :
try {
await detached.wait({ signal: AbortSignal.timeout(5 * 60_000) });
} catch (error) {
if (!(error instanceof DOMException && error.name === "TimeoutError")) {
throw error;
}
await detached.kill(); // the signal only stops waiting, not the command
}
API在一个沙盒里每个成员一次运行最多3个指令,每个成员10个指令
穿越沙盒和目标的工作空间。 任意限制的指令是
以 HTTP 409 拒绝, 以及
超过 API 节点运行时的 100; runCommand() 然后丢出一个
BuddySDKError 带代码 CONCURRENCY_LIMIT,这样你就可以等待运行
命令完成并再次尝试.
命令最长可达16个KB,90分钟后停止,故跑
服务器和其他长寿进程 应用程序它的日志封顶于
10米B,过去 data.truncated 已经设定.
启动和取消命令需要 SANDBOX_USE 符号范围, 其中
SANDBOX_WRITE 包含.
等待准备
Sandbox.create() 直到沙盒设置完毕并到达
RUNNING,因此它返回的例可以使用。 一边等着投票
aPI从100ms开始,成长到500ms.
过 wait: false 跳过等待,自己开车。 你得到的例子
带回所有创建呼叫 id, (中文(简体) ), identifier, (中文(简体) ), url, (中文(简体) ),
resources -但是连接细节还没有解决.
const sandbox = await Sandbox.create({ identifier: "my-sandbox", wait: false });
// ... do other work while the sandbox boots ...
await sandbox.waitUntilReady(); // setup_status: SUCCESS
await sandbox.waitUntilRunning(); // status: RUNNING
服务员接受一个明确的间隔 将投票定在固定值 而不是退后 :
await sandbox.waitUntilRunning(500); // check every 500ms
应用程序
沙盒可以同时运行多个应用程序. 每个应用程序都是由运行命令定义的长期进程,可选 identifier (省略时来自命令)和可选 path 它在运行( 默认为 app_dir) (中文(简体) ).
const sandbox = await Sandbox.create({
identifier: "my-sandbox",
name: "My Sandbox",
os: "ubuntu:24.04",
first_boot_commands: "apt-get update && apt-get install -y curl",
apps: [
{ identifier: "api", command: "node server.js" },
{ identifier: "worker", command: "python worker.py", path: "/app/jobs" },
],
timeout: 600, // auto-stop after 10 minutes of inactivity
});
// List apps
for (const app of sandbox.data.apps ?? []) {
console.log(`${app.identifier}: "${app.command}" -> ${app.app_status}`);
}
// Control individual apps - by identifier or by the generated id
await sandbox.stopApp("api");
await sandbox.startApp("api");
const { logs } = await sandbox.getAppLogs("api");
console.log(logs);
取出仓库和文物
使用 fetch 或将文物下载到沙盒中
第一个靴子。 每个条目设置一个 type (单位:千美元)PROJECT_REPO, (中文(简体) ), PUBLIC_REPO,或
ARTIFACT+ 与之相关的字段.
await Sandbox.create({
identifier: "my-sandbox",
fetch: [
{
type: "PUBLIC_REPO",
repository: "https://github.com/octocat/Hello-World",
ref: "master",
path: "/workspace/hello",
build_command: "echo built",
},
],
});
更新沙盒
使用 sandbox.update() 创建后更改配置 - timeout, (中文(简体) ), apps, (中文(简体) ), endpoints, (中文(简体) ), variables, (中文(简体) ), tags等 (中文(简体) ). 内部状态随API的回应而更新.
const sandbox = await Sandbox.getByIdentifier("my-sandbox");
await sandbox.update({
timeout: 1200,
tags: ["staging", "feature-x"],
});
抓图
取一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一 每个快照都作为 Snapshot 使用自己的方法.
const sandbox = await Sandbox.getByIdentifier("my-sandbox");
// Create a snapshot. Returns immediately with status "CREATING".
const snapshot = await sandbox.createSnapshot({ name: "before-deploy" });
// Wait until the snapshot is "CREATED" before using it.
await snapshot.waitUntilReady();
// Create a new sandbox from the snapshot.
const restored = await Sandbox.createFromSnapshot(snapshot.id, {
name: "restored-sandbox",
});
// List all snapshots for this sandbox.
const snapshots = await sandbox.listSnapshots();
// Delete a snapshot.
await snapshot.delete();
如果您已经从别处获得快照ID( 如在自己的存储中坚持), 请直接获取实体 :
const snapshot = await Sandbox.getSnapshotById(sandboxId, snapshotId);
同等便利方法 Sandbox 仅当您有身份证明而不想要获取 Snapshot 第一条:
await sandbox.waitForSnapshotReady(snapshotId);
await sandbox.deleteSnapshot(snapshotId);
区域
配置 API 区域 :
# Via environment variable (recommended)
export BUDDY_REGION="EU"
// Or via connection config
const sandbox = await Sandbox.create({
identifier: "my-sandbox",
name: "My Sandbox",
os: "ubuntu:24.04",
connection: {
region: "EU" // US, EU, or AS
}
});
连接覆盖
覆盖每个呼叫的工作空间/自动 :
await Sandbox.create({
identifier: "my-sandbox",
name: "My Sandbox",
os: "ubuntu:24.04",
connection: {
workspace: "different-workspace",
project: "different-project",
token: "custom-token",
region: "EU"
}
});
HTTP/2 导弹
SDK通过HTTP/2发送API请求,使用由所有沙盒共享的每个过程16个连接的集合. 改变池大小或使用 fetch (HTTP/1.1)改为:
export BUDDY_HTTP2_SESSIONS="32" # 1-64, default 16
export BUDDY_HTTP2="0" # use fetch instead
在第一个请求之前设定 如果设置了代理变量( E)HTTPS_PROXY, (中文(简体) ), HTTP_PROXY, (中文(简体) ), ALL_PROXY), SDK 使用 fetch: 节点 http2 模块从不通过代理连接,而 fetch 当节点运行时 --use-env-proxy 或者说 NODE_USE_ENV_PROXY=1。 。 。 .