@ execution- assisters/ isb( 执行- 联系)
类型脚本 SDK 义b数字 :
声明式沙盒(容器和VM)。 这是一个瘦客户
isb rpc,一个线性限定的 JSON 协议, 覆盖 isb 二进制的 stdin 和
静态( t)参考文件/参考文件/. isb 工作; SDK 开始
它,发送请求和输入结果.
- 邦先;节点20或后起也行. 仅限无害环境管理.
- 没有运行时间依赖 .
- 光谱对象精确使用作曲 YAML 的字段名 (单位:千美元)文件/参考资料/汇编),因此可以在YAML之间复制一个 spec 密码 SDK选项为骆驼Case.
安装
bun add @execution-associates/isb
软件包有可选的依赖性 @execution-associates/isb-linux-x64
财务报告和审定财务报表 @execution-associates/isb-linux-arm64,每个携带释放的
该平台的签名是 b 二进制, 对照发布签名检查
当软件包用 npm 出处构建和发布时。 用来使用Isb
您安装了安装器, 设置 ISB_BIN=$(command -v isb)编辑
二进制在此顺序中 :
new Client({ isbBin })$ISB_BIN- 平台软件包
bin/isb在里面) ("内地") isb打开PATH
isb 需要访问插件套接字, 这在主机上相当于根 .
快速启动
import { PortBinding, Sandbox, Volume } from "@execution-associates/isb";
const sb = await Sandbox.connectOrCreate({
container_name: "dev-web",
image: "dev-base",
cpus: 4,
mem_limit: "8g",
labels: { app: "web" },
environment: { NODE_ENV: "development" },
volumes: [
Volume.bind("/srv/src", "/home/dev/src", { device: "src" }),
Volume.named("dev-cache", "/home/dev/.cache", { owner: "dev" }),
"/srv/ref:/home/dev/ref:ro", // the short form works too
],
ports: [
PortBinding.publish("5173-5193", 5173, { name: "vite" }), // first free port
"127.0.0.1:8080:80",
],
ready: ["running", "default_route", { user_exists: "dev" }],
user: "dev",
working_dir: "/home/dev/src",
});
console.log(sb.lastReport?.ports); // device name -> listen address in use
// Captured output. argv is never joined into a shell string.
const out = await sb.exec("printf", ["[%s]", "a b"]);
console.log(out.exitCode, out.stdoutText); // 0 "[a b]"
// Streaming output, piped stdin, signals.
const proc = await sb.execStream(["sh", "-c", "cat; echo done >&2"], {
stdin: "piped",
});
await proc.write("hello\n");
await proc.closeStdin();
const decoder = new TextDecoder();
for await (const event of proc) {
process.stdout.write(`${event.kind}: ${decoder.decode(event.data)}`);
}
console.log("exit code:", await proc.wait());
await sb.remove({ force: true });
作曲文件 :
import { Project } from "@execution-associates/isb";
const project = await Project.load({
files: ["isb.yaml"],
vars: { WORKTREE: process.cwd() },
});
console.log(project.name, project.services);
for (const plan of await project.plan()) {
console.log(plan.name, plan.actions);
}
// Like `isb up -d`: resolves once the sandboxes are ready. A service's
// `command` is for the foreground CLI `isb up` and is not run here.
const reports = await project.up({
onProgress: (line) => console.error(line),
});
// A sandbox from the project carries its service's exec defaults.
const web = project.sandbox("web");
await web.exec(["bun", "install"]);
await project.down();
API 密码
客户端
new Client({ isbBin?, socket?, project?, createTimeout?, cwd?, env?, spawner? })
拥有一个长寿 isb rpc 子进程, 始于第一个请求.
socket, (中文(简体) ), project 财务报告和审定财务报表 createTimeout 成为全球旗帜 --socket, (中文(简体) ),
--project 财务报告和审定财务报表 --create-timeout。客户端检查服务器的问候和
拒绝1以外的协议。 请求同时运行并匹配
编号.
每个调用都使用可选对象选项 client如果没有一个
共享 defaultClient() 已使用(setDefaultClient() 改为:.
await client.close()关闭服务器的 stdin 并等待它退出 .await using client = new Client()在范围结束时也这样做.- 闲置的客户端不能让进程活着,所以脚本从不调用
close()仍然离开。 与spawner: "bun"(Bun. spawn 代替:node:child_process,它会一直到close()。 。 。 . - 如果子进程已终止, 待决请求以
ProcessExitedError(带有退出状态并结束其 stderr)和下一个请求开始 一个新的. client.request(method, params, onEvent?)直接发送任何 rpc 方法 .
沙盒
静态 :
| 方法 | 已经 |
|---|---|
Sandbox.create(spec, { baseDir?, volumes?, waitReady?, onProgress? }) | 创建; AlreadyExistsError 如果它存在的话 |
Sandbox.connectOrCreate(spec, { ..., pruneDevices? }) | 创建或调节( e)isb up 一个沙盒; 报告 sb.lastReport |
Sandbox.plan(spec, { baseDir?, volumes?, pruneDevices? }) | 什麽 connectOrCreate 将更改: Plan |
Sandbox.resolve(spec, ...) | 针对此主机的 spec 解析 |
Sandbox.get(name) | 现有沙盒; NotFoundError 如果缺少 |
Sandbox.listWith({ labels }), (中文(简体) ), Sandbox.list() | SandboxInfo[]标签为 { key: "value", other: null } 或者说 ["key=value", "other"] |
Sandbox.remove(name, { force? }) | 删除; 运行中需要 force |
spec 是一个 SandboxSpec (单位:千美元) services.<service> 作曲对象
格式)与 container_name (实例名称)和 image 所需经费.
baseDir 锁定相对绑定路径( 默认: 子进程正在工作)
目录). volumes 持有名量定义, 如作曲文件
顶级 volumes:: 一个山上 source 名称定义的密钥,以及
该定义是 name,否则键本身(一个没有
定义使用 source 作为主音量名称. onProgress 接收
线条例如 web: creating from dev-base。 。 。 .
实例 : info(), (中文(简体) ), labels(), (中文(简体) ), start(), (中文(简体) ), stop({ force?, timeout? }), (中文(简体) ),
restart(), (中文(简体) ), waitReady({ ready?, readyTimeout? }), (中文(简体) ), remove({ force? }), (中文(简体) ),
addPort(port) 联合国 ports 条目; 返回正在使用的收听地址 , removeDevice(name)
(返回它是否在那里), exec(...), (中文(简体) ), execStream(...)。 。 。 .
一个沙盒由 create, (中文(简体) ), connectOrCreate 或者说 project.sandbox() 记得
spec的执行默认, user, (中文(简体) ), working_dir, (中文(简体) ), exec.env 财务报告和审定财务报表 exec.login
(同意每个执行官,作为 sb.execDefaults页:1 ready 财务报告和审定财务报表
ready_timeout (使用时间: waitReady() . . . . . . 一个来自 get 没有.
execDefaultsOf(spec) 计算相同的默认值.
执行
sb.exec(cmd, args?, {
cwd?,
user?,
env?,
login?,
timeout?,
stdin?,
tty?,
width?,
height?,
})
cmd 程序为 args 作为其参数,或整个 argv 数组.
timeout 是秒或持续时间字符串("90s", (中文(简体) ), "5m";通过命令
被杀死,电话被拒绝 IsbTimeoutError (单位:千美元)code: "exec_timeout") (中文(简体) ).
stdin 是一个字符串或字节。 单调选项覆盖沙盒的执行
默认值.
它决定一个 ExecOutput数字 : exitCode, (中文(简体) ), stdout 财务报告和审定财务报表 stderr (字节),和
获取器 stdoutText, (中文(简体) ), stderrText 页:1 success (出站码为0). A 类
非零退出代码不是一个错误.
sb.execStream(cmd, args?, opts) 选择相同的选项 stdin (单位:千美元)
接受 "piped",并决心 ExecProcess 只要请求是
发送时间 :
for await (const ev of proc)数字 :{ kind: "stdout" | "stderr", data: Uint8Array }按每条溪流顺序排列。 一个消费者。 输出被缓冲直到读取 .write(data), (中文(简体) ),closeStdin(): 与stdin: "piped"。 。 。 .signal(15)或者说signal("SIGTERM"), (中文(简体) ),resize(width, height)(仅限).wait():出站代码.output():读完其余内容,然后返回ExecOutput。 。 。 .
与 tty: true 所有输出都以stdout的形式到达.
构建器
他们把服务品的普通条目还给我 volumes 财务报告和审定财务报表 ports 列表,列在
长窗体; 短字符串 ("./src:/home/dev/src:ro", (中文(简体) ), "8080:80"可能会是
自由混杂.
Volume.bind(hostPath, target, { readOnly?, device?, options? })数字 :{type: "bind", source, target, ...}。 。 。 .Volume.named(name, target, { external?, owner?, readOnly?, pool?, device?, options? })数字 :{type: "volume", source, target, ...},如果缺少则创建,除非external: true(音量必须存在).PortBinding.publish(published, target, { hostIp?, protocol?, name?, options? })数字 : 多克的长端口形式.hostIp默认为 127.0.0.1.Apublished范围 (单位:千美元)"5173-5223"单人target取其中的第一个自由端口.PortBinding.host(listen, connect, { name?, search?, options? }): 线索 代理在主机上监听,并在嘉宾中连接,并加注 地址(5173, (中文(简体) ),"0.0.0.0:5173", (中文(简体) ),"5353/udp", (中文(简体) ),"tcp:HOST:PORT") (中文(简体) ).search: N返回 apublish输入范围listen.listen+N转而投出TypeError当地址无法写入时 方式(一个端口范围,一个unix socket,一个连接主机而不是默认).PortBinding.guest(listen, connect, { name?, options? }): 倾听在 宾客,在主机上连接.
项目(组成)
Project.load({ files?, envFiles?, projectName?, vars?, client? }) 负载,
插入并合并不触碰主控的文件。 无 files
写着 isb.yaml (或 isb.yml)在子进程的工作目录中,加
isb.override.yaml (或 .yml旁边;无 envFiles, (中文(简体) ), .env 旁边
第一个文件如果存在. vars 胜过isb的环境
子进程和 env 文件。 该项目已经
name, (中文(简体) ), baseDir, (中文(简体) ), files, (中文(简体) ), file (决 议 ComposeFile和 services。 。 。 .
up({ services?, pruneDevices?, waitReady?, onProgress? })数字 :[{ service, report }]plan({ services?, pruneDevices? })数字 :Plan[]down({ services?, volumes?, onProgress? })spec(service), (中文(简体) ),sandbox(service)
音量和音量
volumes.list({ pool? }), (中文(简体) ),volumes.get(name, { pool? }), (中文(简体) ),volumes.create(name, { pool?, config? })(单位:千美元){ created, pool }, (中文(简体) ),volumes.remove(name, { pool? })prune(label, { dryRun? }): 砂盒,其label值是一个主机路径 已经不复存在。 干燥,除非dryRun: false。 。 。 .
类型
类别SandboxSpec, (中文(简体) ), VolumeSpec =字符串 === VolumeMount, (中文(简体) ),
PortSpec =字符串 === PortMapping | ProxyPort, (中文(简体) ), MapOrList, (中文(简体) ), Command, (中文(简体) ),
ExecSpec, (中文(简体) ), ReadyCheck, (中文(简体) ), IdmapSpec, (中文(简体) ), NamedVolumeSpec, (中文(简体) ), ComposeFile, (...) (中文(简体) )
从 isb schema 输入 src/spec.ts。结果如下: SandboxInfo, (中文(简体) ),
ApplyReport, (中文(简体) ), Plan (与 Action 工会,由 action, (中文(简体) ),
VolumeInfo, (中文(简体) ), PruneItem· ; ExecDefaults 是执行- 默认形状 rpc
方法选择。 结果的字段名称是 Isb 发送它们
(snake case) (英语).
错误
每一个失败都是以 IsbError 携带 code, (中文(简体) ),
message 财务报告和审定财务报表 data (文件/参考资料/rpc.md列出它们)。 按代码划分的子类 :
| 类 | 代码 |
|---|---|
NotFoundError | not_found |
AlreadyExistsError | already_exists |
NotReadyError | not_ready |
IsbTimeoutError | request_timeout, (中文(简体) ), operation_timeout, (中文(简体) ), exec_timeout |
InvalidError | invalid, (中文(简体) ), interpolation, (中文(简体) ), parse |
ConnectError | connect (责任无法到达; data.socket(中文(简体) ) |
ProtocolError | protocol (也是一种未知的方法), bad_request, (中文(简体) ), websocket一个糟糕的你好 |
ProcessExitedError | process_exited: 无法启动或死亡子进程 |
ClientClosedError | closed: 客户端已关闭 |
IsbError | 其它东西api, (中文(简体) ), operation_failed, (中文(简体) ), io, (中文(简体) ), json(中文(简体) ) |
发展
类型由isb 二进制的系统生成 :
ISB_BIN=/path/to/isb bun run gen-types # rewrites src/spec.ts
Dev 依赖性(TypeScript, Biome, json-schema- to-typescript)仅用于
字型检查、林入、类型生成和建筑。 测试导入自
src/ 只有,所以他们跑没有 bun install数字 :
ISB_BIN=/path/to/isb bun test # unit tests, no incus
ISB_INTEGRATION=1 ISB_BIN=/path/to/isb bun test # plus integration tests
bun install && bun run typecheck && bun run lint && bun run build
单位测试运行真实 isb rpc 对不存在的套接字,加
小假服务器. 一体化测试需要加强,当地形象需要
dev 用户在 uid 1000(ISB_TEST_IMAGE默认值 dev-base) (中文(简体) ). 所有他们
创建名称 isb-test-ts-<pid>-... 并被清除后,通过或失败.
许可证
SDK是麻省理工学院的.
其安装的平台包( :@execution-associates/isb-linux-x64, (中文(简体) ), @execution-associates/isb-linux-arm64(b) 承接在 执行助理 来源 许可证 1.0 (EXA-SL-1.0) (中文(简体) ).