提供方模板部署
在 GitHub 查看 ↗提供方模板部署
状态:设计,尚未实现。本文不修改 EPP/1、引擎、现有 18 个功能 id,也不修改任何提供方插件。这些改动需要先批准本文。
English:
../../design/provider-template-deploy.md2026-10-15 读过的代码:
agent-sandboxa20f497,awesome-providers873f033。同一天抓取的上游页面在正文里引用。没有在这些树或页面里读到的内容标为未验证。
1. 安装表在说什么
“可直接安装/构建”“需要已有模板 id”“先推送镜像”这三句不在上述提交的本仓库或 awesome-providers 里,对公开 registry 站点的检索也没有返回使用这些字句的页面。CLI 里已有的页面是安装之后能跑什么。它把 18 个功能 id 映射到命令。alicloud-express 看起来支持全部命令,是因为 src/providers/builtin.ts 把 this.features 设成完整的 FEATURES。四个目录插件都没有声明 templates.read 和 templates.build。
abx template deploy 在 Docker、ACR 或 CreateTemplate 之前调用 requireTemplateFeature("templates.build")(src/cli/template_provider.ts,部署回调在 src/cli/commands/template.ts)。目录提供方因此返回 E8004,不会走进极速版的仓库流程。provider-wiring-plan.md 里 2026-10-13 那条“模板命令忽略 --provider,失败信息是 ACR credentials missing”在当前 main 上已经过时。
新功能落地之后,表应该这样显示:
提供方声明了 template.deploy |
sandbox.create 已经接受的值 |
标签 |
|---|---|---|
| 是 | deploy 返回的 id 或引用 | 可直接构建 |
| 否 | 该后端上已经存在的 id | 需要已有模板 id |
| 否 | 容器镜像 URI | 先推送镜像 |
极速版今天落在第一行,是因为 CLI 而不是极速版 API 在构建镜像、推送、注册模板并等到 READY。平台调用仍然只收模板 id。
应该共用这条路径的调用方:
abx template deploy <dir>和abx deploy <dir>(src/cli/commands/template.ts、src/cli/commands/deploy.ts)。- Python SDK 不部署。它的指南让调用方去跑 CLI(
python-sdk的docs/en/guide/authoring-templates.md)。以后 SDK 的部署走第 5 节的引擎路由,不另写一条流水线。 awesome-templates/scripts/express_e2e.py调abx template deploy,再abx create/abx run。它会清掉ABX_PROVIDER,并且只打极速版。某个提供方实现了template.deploy之后,这个脚本可以带上--provider,冒烟步骤保持不变。
2. 七个步骤,以及谁负责
| 步骤 | 今天做什么 | 本设计之后 |
|---|---|---|
| 1. 解析构建计划 | src/template/build_plan.ts 的 resolveBuildPlan 读 template.yaml 和 Dockerfile。auto 优先 Dockerfile。steps 把 build: 展开成 {type, args}。 |
CLI。提供方不解析 template.yaml。 |
| 2. 构建镜像 | _buildImage 里本地 docker build,含 server-sdk wheel 或归档钉。极速版 steps 模式跳过 Docker,把步骤交给 CreateTemplate。 |
build: local 归 CLI。build: remote 归提供方(E2B 在服务端跑步骤)。 |
| 3. 推到提供方拉得到的仓库 | _pushImage 推到 ACR(默认 registry.cn-hangzhou.aliyuncs.com)。 |
提供方声明 push: registry 并给出仓库名时,用 CLI 的推送助手。提供方远程构建,或镜像已经是提供方能拉的公开引用时,跳过。 |
| 4. 注册或创建模板 | src/api/fc_template.ts 的 fc_template.createOfficialTemplate,官方 FCSandbox CreateTemplate。 |
提供方方法 template.deploy。 |
| 5. 等到 READY | 同一模块的 waitForTemplateReady。步骤模式返回 submitted,不等待。 |
提供方。它发出进度,只在 status 终态或 submitted 时返回。 |
| 6. 返回 id 或引用 | TemplateID。_rememberTemplate 把 template.yaml 缓存在该 id、别名和 yaml 名称下。 |
提供方结果里的 template_id(sandbox.create 接受的字符串)以及可选的 ref。缓存仍由 CLI 做。 |
| 7. 删除、列出、查看 | fc_template.ts 里的极速版 list/get/delete,由 templates.read / templates.build 把关。 |
提供方方法 template.list、template.get、template.delete。 |
abx-provider.toml 里的 [template] 是编写期画像(src/providers/template_profile.ts:基础镜像、server_start、Dockerfile 的 CMD)。它不是 abx create --template 的运行时含义。OpenSandbox 没有 [template] 表,用的是通用画像(FROM python:3.12-slim,CMD ["python3", "commands.py"])。
3. 各提供方
3.1 alicloud-express(内置)
原生模板:CreateTemplate 产生的极速版模板 id。API 接收镜像引用(步骤模式还有 sandboxConfig.steps)、CPU、内存、磁盘、generation、startCommand、readyCommand。它不接收本地目录。start 和 ready 命令需要 generation 2。同名的 generation 1 模板不能就地改成 generation 2(fc_template.ts 里的 GEN1_START_COMMAND)。
这个平台没有 CMD 或 ENTRYPOINT。画像的 server_start 是 platform_start_cmd。目录里有 commands.py 且没有显式 generation 时,resolveDeployRuntime 按 generation 2 发布,并带上:
- start:
agent-sandbox-server serve --port 9000 --commands /home/user/app/commands.py - ready:
agent-sandbox-server healthcheck --port 9000
template.yaml 字段 |
极速版 |
|---|---|
base / base.image |
Dockerfile 的 FROM,或步骤模式的镜像。占位符 <region>、<tag> 会换成 FC 基础镜像。 |
generation |
会发送。画像负责启动服务且存在 commands.py 时默认 2,否则 1。 |
start_cmd、ready_cmd |
generation 2 时发送。 |
resources.cpu、resources.memory |
会发送。文件没写时 CLI 默认 2 CPU、2048 MB。 |
ports |
不传给 CreateTemplate。留在缓存的 template.yaml 里供能力查找。 |
env |
这条路径上不是 CreateTemplate 的字段。 |
凭证:ALICLOUD_ACCESS_KEY_ID、ALICLOUD_ACCESS_KEY_SECRET(也是 ACR 用户名和密码的默认值)、ACR_NAMESPACE、ALIBABA_CLOUD_REGION_ID,再加上创建和运行用的 ABX_SANDBOX_API_KEY、ABX_SANDBOX_BASE_URL、ABX_SANDBOX_DOMAIN。插件不读 E2B_*。
已验证:template.ts / fc_template.ts / build_plan.ts 里的流水线,以及功能门闩。这个 CLI 的极速版真实部署记录在更早的改动里;本设计没有新跑一次。
3.2 e2b
插件:awesome-providers/e2b/provider.mjs。buildInfra 用宿主的 E2B 协议类打 https://api.e2b.app,请求头是 X-API-Key。创建是带 templateID 的 POST /sandboxes。清单没有声明模板功能,所以 deploy 是 E8004。README:单元测试打本机假 API;这台环境没有 ABX_E2B_API_KEY,没有做真实创建。
原生模板:E2B 模板 id(和别名),Sandbox.create(template=...) 把它当作 templateID。构建完成是一份快照:startCmd 在构建期间运行,readyCmd 必须退出码 0,快照里包含正在运行的进程。之后的 create 不会重跑 start 命令(Start & ready commands)。
V1“直接提交 Dockerfile”的 API 已经停用。V1 build system deprecation 写明 V1 构建在 2026-08-01 停止,e2b template build 只是一个立即退出的存根。公开 OpenAPI 把带 dockerfile 字符串的 POST /templates 和 POST /v2/templates 都标成 deprecated。当前的构建是:
POST /v2/templates,字段alias、cpuCount、memoryMB。响应202带templateID和buildID(Create template (v2))。POST /v2/templates/{templateID}/builds/{buildID},fromImage与fromTemplate恰好给一个,加上steps、startCmd、readyCmd,以及可选的fromImageRegistry(aws、gcp或registry)(Start build (v2))。GET /templates/{templateID}/builds/{buildID}/status。状态包括building、waiting、ready、error、uploaded(Get build status)。
Dockerfile 由客户端的 Template.fromDockerfile 解析成这些步骤。支持的指令:FROM、RUN、COPY、ADD、WORKDIR、USER、ENV、ARG、CMD、ENTRYPOINT。EXPOSE 和 VOLUME 会被跳过(Base image)。另一条路是 fromImage:本地构建、推送,再把标签和仓库凭证传上去。步骤在 E2B 的服务器上执行。公开基础镜像的步骤构建不需要本地 Docker。
| 字段 | E2B |
|---|---|
base |
fromImage,或解析后的 Dockerfile 的 FROM。 |
generation |
没有这个字段。不支持。 |
start_cmd、ready_cmd |
startCmd、readyCmd。它们在构建时运行,然后进程被做成快照。 |
cpu、memory |
创建模板时的 cpuCount、memoryMB。 |
ports |
EXPOSE 被跳过。构建请求里没有端口。 |
env |
ENV 变成一个步骤。创建时传入的环境变量对 startCmd 不可见,因为那个进程已经跑过了。 |
build.steps / build.run |
CLI 已经产出 {type, args} 步骤。提供方把 RUN/ENV 映射到 E2B 的 TemplateStep。具体步骤 JSON 没有抄进本文;实现时对照当时的 OpenAPI。 |
凭证:公开基础镜像只需要 ABX_E2B_API_KEY。私有 fromImage 还要在 fromImageRegistry 里带仓库凭证。插件不读 ABX_SANDBOX_API_KEY,也不读 E2B_API_KEY。
已验证:插件源码、清单,以及上面链接的 E2B 文档。未验证:一次真实构建、TemplateStep 的模式,以及 COPY/ADD 如何上传文件字节(start-build 页面有 steps,没有文件上传的请求体)。
3.3 cubesandbox
插件:awesome-providers/cubesandbox/provider.mjs。它说的是 E2B 形状的 CubeAPI(带模板 id 的 POST /sandboxes),另加 Cube 自己的 resume、端口,以及 49999 上的 Jupyter。清单没有模板功能。README:用集群里真实存在的模板 id,不要假设有 base。单元测试打假 API。没有做真实创建(3000 端口上没有服务)。
原生模板:服务端生成的 id(tpl- 前缀)。CubeAPI 的 POST /templates 接受 CreateTemplateRequest,返回 202,带 jobID、templateID、status、phase、progress(CubeSandbox openapi.yml,operationId: create_template)。必填字段是 image。还有:name、alias、cpu(毫核)、memory(MiB)、command、args、env(KEY=VALUE 字符串)、exposedPorts、probePort、probePath(设了探测端口时默认 /health)、registryUsername、registryPassword、writableLayerSize、allowInternetAccess。请求里的 templateID 会被忽略。状态走 GET /templates/{templateID}/builds/{buildID}/status。
cubemastercli tpl create-from-image 是文档里的操作路径(Creating Templates from OCI Images)。镜像必须能被 CubeMaster 节点拉到。公开仓库不需要凭证。私有仓库需要 --registry-username 和 --registry-password。纯 HTTP 仓库的镜像引用要加 http:// 前缀。单节点集群可以用本地镜像名,不必推送(Local and Remote Image Template Practice)。--enable-inject-envd 在 CLI 的 multipart 请求里上传 envd 二进制(Custom Template Images)。这里读到的 CreateTemplateRequest 没有这个字段。
| 字段 | CubeSandbox |
|---|---|
base |
不是模板基础镜像。推上去的镜像就是 image。 |
generation |
不支持。 |
start_cmd |
command 加 args(覆盖入口),不是极速版那种平台 start 命令。 |
ready_cmd |
probePort 和 probePath。没有 shell ready 命令字段。 |
cpu、memory |
cpu 用毫核(2 核 → 2000),memory 用 MiB。 |
ports |
exposedPorts。探测端口应该是其中之一。 |
env |
env,格式 KEY=VALUE。 |
凭证:ABX_CUBESANDBOX_BASE_URL(默认 http://127.0.0.1:3000)、可选的 ABX_CUBESANDBOX_API_KEY、ABX_CUBESANDBOX_DOMAIN、ABX_CUBESANDBOX_PROXY。仓库用户名和密码是请求字段,今天的清单里没有。实现时加成配置字段,跟 OpenSandbox 已有的 registry_username / registry_password 一样。
已验证:插件、清单、README,以及 OpenAPI 和那三篇教程。未验证:对真实 Cube 集群的一次任务,以及 POST /templates 能不能注入 envd,还是只有 cubemastercli 可以。
3.4 alicloud-container
插件:awesome-providers/alicloud-container/provider.mjs。这是 ACS/ACK 的 sandbox-manager,说 E2B 形状的 HTTP,不是极速版。native 的 API 是 https://api.{domain};private 是 https://{domain}/kruise/api。创建是带模板 id 的 POST /sandboxes。提供方 README 里的例子是 code-interpreter。清单没有模板功能。单元测试用假 API。这台环境没有 ACS/ACK 集群,没有做真实创建。
原生模板:一个 SandboxSet(agents.kruise.io/v1alpha1)的名字。ack-sandbox-manager 监视这个对象,并把它的名字暴露成 E2B 模板 id。镜像是 SandboxSet Pod 模板里的字段,例如 registry-<region>-vpc.ack.aliyuncs.com/acs/code-interpreter:v1.6(Create an Agent Sandbox in an ACS cluster)。单次创建换镜像用的是 Sandbox.create 上的元数据 e2b.agents.kruise.io/image,仍然需要一个已有的模板名。组件变更说明里写了它支持模板的 list 和 get。这个插件没有打那些路由。
这个插件所讲的 E2B 兼容 HTTP 里没有 CreateTemplate。注册一个新模板意味着向集群提交 SandboxSet。那是 Kubernetes 写操作,插件没有这类凭证。
| 字段 | 容器版 |
|---|---|
base |
操作者提交的 SandboxSet 里的容器 image,或创建时的元数据镜像覆盖。 |
generation、start_cmd、ready_cmd |
POST /sandboxes 上没有这些字段。Pod 命令写在 SandboxSet 里。 |
cpu、memory |
SandboxSet 的 Pod resources,不是这个插件发送的创建正文。 |
ports、env |
Pod spec。插件没有映射。 |
创建用的凭证:ABX_ALICLOUD_CONTAINER_DOMAIN、ABX_ALICLOUD_CONTAINER_API_KEY,可选 ABX_ALICLOUD_CONTAINER_BASE_URL 和 ABX_ALICLOUD_CONTAINER_PROTOCOL。推镜像用集群节点拉得到的 ACR(VPC 仓库地址)。插件今天没有 ACR 或 Kubernetes 配置。
已验证:插件、清单、README,以及 ACS 文档页。未验证:模板 list/get 的真实响应,以及任何能创建 SandboxSet 的 HTTP。在确认那条 API 之前,把“deploy 能造出模板 id”视为不支持。
3.5 opensandbox
插件:awesome-providers/opensandbox/provider.mjs 和 src/sandbox.mjs。sandbox.create 用 resolveImage 把模板字符串变成镜像 URI:空或 base → default_image(python:3.12-slim);配置的别名(code → opensandbox/code-interpreter:v1.1.0);其他字符串按 URI 使用。正文是 image.uri、entrypoint、resourceLimits(cpu 用毫核,memory 如 512Mi),以及可选的 image.auth、env、timeout、metadata、networkPolicy、platform、secureAccess。插件随后等到状态 Running 且 execd 的 /ping 有响应。templates.list、templates.get、templates.delete、templates.build、templates.build_status 被写死成不支持错误,因为清单没有声明这些功能。
上游生命周期规范(2026-10-15 抓取的 alibaba/OpenSandbox main 上的 specs/sandbox-lifecycle.yml):创建在 image、snapshotId 和池引用里取一个。给了 image 就必须有 entrypoint。非池模式必须有资源限制。提供方 README 实测过的运行时是 Docker(2026-10-14 本机 1.1.1:创建、执行、文件、终端、端口 URL)。
POST /v1/templates 创建 fsb 黄金镜像模板。规范写明它在 kubernetes 和 fsb 运行时上可用,Docker 上返回 501。请求体(CreateFsbTemplateRequest)必填 image 和 publish(S3 风格的目标)。可选:resourceLimits、entrypoint(默认 ["tail", "-f", "/dev/null"])、env、metadata、readiness、format(native 或 overlaybd)。轮询 GET /v1/templates/{templateId},直到 status.phase 为 Succeeded 或 Failed。模板 id 形如 tpl_…。内核、execd 和客户机初始化来自服务端配置,不是客户端字段。已经用该模板创建的沙箱在删除模板后仍保留自己的产物。
| 字段 | OpenSandbox |
|---|---|
base |
构建并推送的那份镜像。sandbox.create 把这个引用当作 template。 |
generation |
不支持。 |
start_cmd |
entrypoint 参数数组。提供方的 entrypoint 配置会覆盖镜像。通用镜像用 tail -f /dev/null 保持运行,这样 execd 才能提供执行和文件。在 9000 端口提供服务的生成镜像把 entrypoint 设成 python3 commands.py。 |
ready_cmd |
创建请求没有这个字段。插件等待 Running 和 execd /ping。Fsb 的 readiness 只在 POST /templates 上。 |
cpu、memory |
resourceLimits.cpu(2 → 2000m),resourceLimits.memory(2048 → 2048Mi)。创建时省略则插件默认 500m 和 512Mi。 |
ports |
不是创建字段。ports.url 调用 GET /v1/sandboxes/{id}/endpoints/{port}。 |
env |
创建请求上的 env 对象。Fsb 模板把环境变量烤进黄金镜像。 |
凭证:ABX_OPENSANDBOX_BASE_URL(默认 http://127.0.0.1:8080),可选 ABX_OPENSANDBOX_API_KEY(OPEN-SANDBOX-API-KEY)。私有镜像用 registry_username 和 registry_password(image.auth)。服务器必须拉得到这个引用。Fsb 构建还需要 S3 的 publish 目标,今天没有这个配置字段。
已验证:插件源码、清单、提供方 README,以及生命周期规范。未验证:对 Kubernetes 运行时的一次真实 POST /templates,以及本 CLI 推上去的镜像被真实拉取。
4. 其他提供方能不能在插件里做同样的事
注册、等待、删除这一半可以。如果“同样的事”是指插件自己跑 Docker 和 ACR,则不行。
- CLI 保留步骤 1、本地构建、推送助手和 yaml 缓存。这些对每个提供方都一样,已经在
build_plan.ts、docker_builder.ts和template.ts里。 - 插件对着自己的 API 实现步骤 4–7;能远程构建时也实现步骤 2。
e2b可以收下规范化的步骤列表并返回模板 id,公开基础镜像时不需要本地 Docker。前提是 Dockerfile 指令在支持集合里,并且实现者能上传COPY的源文件。- Docker 上的
opensandbox没有对象要注册。Deploy 推送镜像并返回该引用。sandbox.create已经接受它。Fsb 模板 API 是同一方法在 Kubernetes 上的第二种实现。 cubesandbox注册镜像并等待任务。插件需要仓库凭证和探测端口。alicloud-container不能通过这个插件使用的 HTTP API 造出模板 id。Deploy 可以推送镜像,并写明操作者必须提交的SandboxSet;那些路由接上之后也可以 list 或 get。在创建 API 出现之前,它不应该声明template.deploy。镜像覆盖元数据仍然需要已有模板 id,所以表上的标签仍是“需要已有模板 id”。
express_e2e.py 和 SDK 随后能按提供方工作,是因为它们调用 abx template deploy(或引擎),提供方 id 选中插件。脚本仍然需要该提供方的凭证和拉得到的仓库。没有这些时,它不应该把该提供方写成已验证。
5. 协议变更(批准前不要实现)
5.1 功能 id
新增四个可选 id。不要删除或重命名 src/providers/base.ts 里现有的 18 个:
| Id | EPP 方法 | 引擎 | CLI |
|---|---|---|---|
template.deploy |
template.deploy |
POST /v1/templates |
template deploy、template build、template push、template create、template install(--download-only 除外)、deploy |
template.list |
template.list |
GET /v1/templates |
template list |
template.get |
template.get |
GET /v1/templates/:id |
template info |
template.delete |
template.delete |
DELETE /v1/templates/:id |
template delete |
src/providers/manifest.ts 在安装时拒绝 FEATURES 以外的 id(unknown feature(s): …)。awesome-providers/docs/authoring.md 和 docs/en/create.md 写的是同一个 18 个 id 的封闭列表。宿主允许列表变长之前就让插件声明 template.deploy,abx provider install 会失败。顺序:宿主允许列表、docs/design/fixtures/epp-methods.json、引擎,以及 Python SDK 里的同一份列表,放在同一次发布;插件放在下一次。
旧插件不声明新 id,安装行为与现在相同,deploy 得到 E8004。引擎对同一个缺口返回 501(engine-api.md)。
templates.read 和 templates.build 留在这 18 个里。一个发布周期内宿主把它们当作别名:templates.read 满足 template.list 和 template.get;templates.build 满足 template.deploy 和 template.delete。内置提供方继续声明旧 id,这样现有清单和文档仍然有效。目录插件只声明自己实现了的新 id。内置提供方自己改用新 id、提供方指南里的表也更新之后,下一个发布再去掉这个别名。orderedFeatures 已经会把未知 id 追加到末尾;安装拒绝意味着清单不能依赖那条路径。
initialize 可以带一个可选的 template 对象。只读 features 的宿主忽略它。
{
"build": "remote",
"accepts": ["image", "steps", "dockerfile"],
"push": "none"
}
build 取 local、remote 或 none。accepts 是该方法能处理的请求形式。push 取 none 或 registry。缺了这个对象时 CLI 不猜测:它只在本地构建并推送之后发送 image,这与极速版一致。
5.2 请求和响应
template.deploy 的参数:
{
"name": "my-template",
"alias": null,
"source": {
"kind": "image",
"image": "registry.example.com/ns/my-template:latest"
},
"spec": {
"cpu": 2,
"memory_mb": 2048,
"disk_mb": null,
"ports": [9000],
"env": {"LOG_LEVEL": "info"},
"start_cmd": null,
"ready_cmd": null,
"entrypoint": ["python3", "commands.py"],
"generation": null
},
"registry": {"username": null, "password": null},
"force": false
}
source.kind 的取值:
| kind | 字段 | CLI 何时发送 |
|---|---|---|
image |
image(字符串引用) |
推送助手完成之后,或计划本身已是提供方能拉的镜像。 |
steps |
image(基础镜像)和 steps([{ "type": "RUN", "args": ["…"] }],即 build_plan.ts 的形状) |
提供方 build 为 remote 且 accepts 含 steps。 |
dockerfile |
dockerfile(文件文本)和 files([{ "path", "sha256", "bytes_b64" }]) |
提供方 accepts 含 dockerfile。Dockerfile 没有 COPY 或 ADD 时省略 files。 |
CLI 在调用前把 template.yaml 规范化进 spec。提供方忽略自己不支持的字段,并在一条进度事件里列出被忽略的字段,让命令输出看得见。映射不可能时拒绝调用(Cube 没有镜像、容器版没有 SandboxSet API)。
结果:
{
"template_id": "tpl_or_platform_id",
"ref": "registry.example.com/ns/my-template:latest",
"status": "ready",
"build_id": "bld_123"
}
template_id 是传给 sandbox.create 的 template 字符串。Docker 上的 OpenSandbox 这个字符串就是镜像引用,ref 与它相同。status 取 ready、submitted 或 error。提供方没有构建对象时 build_id 为 null。
template.list 参数:cursor、limit。结果:{ "templates": [{ "template_id", "name", "status", "ref" }], "next": null }。
template.get 参数:template_id。结果:同样字段的一个对象,后端返回了规格时再加上 spec。
template.delete 参数:template_id。结果:{}。不存在的模板算成功,与 sandbox.kill 一致。
5.3 进度
EPP 在 src/providers/epp.ts 里已有两种流:方法为 log 的通知是调试行;带 process_id 的通知进入执行流的队列。模板部署复用通知。插件发出没有 id 的行:
{
"jsonrpc": "2.0",
"method": "template.progress",
"params": {
"build_id": "bld_123",
"phase": "register",
"message": "pulling image",
"progress": 40
}
}
phase 取 build、push、register 或 wait。progress 是 0–100 或 null。宿主按 build_id 排队,方式与按 process_id 排队的执行事件相同。
引擎已经为 commands/stream 和 files/watch 提供 SSE。POST /v1/templates 在 Accept: text/event-stream 时写出 progress 事件和最后的 result 事件。JSON 调用方阻塞到结果记录。没有 template.deploy 时返回 501。错误正文仍是引擎的错误对象。
CLI 的步骤报告器(template.ts 里的 _StepReporter)打印这些事件。本地 docker 和推送的输出仍由它自己打印,因为那两步发生在提供方调用之前。
5.4 CLI 拆分
- 解析提供方。要求
template.deploy。 resolveBuildPlan和resolveDeployRuntime(generation 与 start/ready 只对接受它们的提供方有意义;极速版接受)。- 从提供方描述里读
template。远程构建:发送steps或dockerfile,跳过 Docker。否则_buildImage,并且在push为registry时用_pushImage推到提供方配置里的仓库。 - 调用
template.deploy。把template.yaml缓存在template_id、别名和 yaml 名称下(cacheDeployedTemplate已经实现)。 template list|info|delete调用对应方法。它们不再直接导入fc_template.ts。
极速版走到同一次调用后面。AlicloudExpressProvider 用现有的 fc_template.ts 函数实现这四个方法。ACR 推送留在 CLI,因为提供方声明的是 build: local、accepts: ["image", "steps"]、push: registry。步骤模式仍然跳过 Docker。template.ts 里不再把内置提供方当成特例。
5.5 界面
安装表从提供方信息读取 template.deploy 和创建参数的种类:
- 有
template.deploy→ “可直接构建”。 - 没有,且创建接受的是不透明 id(
e2b、cubesandbox、alicloud-container)→ “需要已有模板 id”。 - 没有,且创建接受的是镜像 URI(
opensandbox)→ “先推送镜像”。
abx provider info 已经会打印功能 id。不需要新命令。手写标签会漂;功能标志才是来源。
6. 实现计划
这一节里的工作都还没有批准编码。
| 仓库 | 工作 | 工作量 | 风险 |
|---|---|---|---|
agent-sandbox |
把四个 id 加进 FEATURES、清单校验、epp-methods.json、引擎路由和提供方指南(中英)。旧模板 id 在一个发布周期内做别名。把极速版的注册/等待/列出/删除挪到这些方法后面。构建计划、本地 Docker 和推送助手留在 CLI。 |
中等。行为变化在分发,不在新的极速版 API。 | 现有极速版部署测试继续通过、并且有一个假插件覆盖模式时,风险低。Python 夹具列表没有在同一次改动里更新时风险高:并排夹具测试会失败。 |
python-sdk |
SDK 允许列表和引擎客户端里同样的四个 id(POST/GET/DELETE /v1/templates)。不另写构建流水线。 |
小,必须和 CLI 改动一起落地。 | 低。只改 SDK 并不能部署。 |
awesome-providers |
宿主发布之后,一个插件一个 PR。只声明该插件实现了的 id。在现有 cli/tests/test_providers/test_node_plugins.test.ts 的假服务旁边加测试。 |
见下面的顺序。 | 插件声明了宿主还不认识的 id 时,安装失败。 |
awesome-templates |
scripts/express_e2e.py 增加提供方参数,并在证据文件里记下该提供方。在该提供方的 deploy 可用之前,脚本仍只跑极速版。 |
小,至少一个插件之后。 | 低。脚本不得为没有真正部署的提供方写证据。 |
提供方顺序:
- E2B,第一个。 用
template.yaml的build:或解析后的 Dockerfile 做远程步骤,公开基础镜像,只需要ABX_E2B_API_KEY。这条路径没有本地 Docker,也没有仓库。工作量:RUN/ENV步骤为中低。风险:中等,因为COPY上传未验证,而且文档仍让调用方使用已被标成 deprecated 的POST /v2/templates。Dockerfile 超出支持的指令集合时,必须报出那条指令,不能做半截构建。 - OpenSandbox 的 Docker 运行时,第二个。 本地构建、推送、返回镜像引用。创建路径已经接受它。工作量:低。服务器能拉到该仓库时风险低。私有仓库用已有的
registry_username/registry_password。Fsb 的POST /templates是后面的一片(Kubernetes 加上 S3 的publish目标)。那一片工作量高、风险高。有集群之前不要声明。 - CubeSandbox,第三个。
POST /templates加状态轮询。工作量:中等。风险:中高。节点必须拉得到镜像,探测必须对上进程,envd注入可能只在cubemastercli上。镜像里没有envd、又没有注入路径的模板,创建之后执行会失败。 alicloud-container,最后。 不要声明template.deploy。管理器路由有响应的话,可以做可选的template.list和template.get。把创建SandboxSet包进插件的工作量高,而且需要插件现在没有的 Kubernetes 凭证。风险高。表上诚实的标签仍是“需要已有模板 id”。
极速版是 CLI 那次改动里的参考实现,排在目录插件之前,这样模式先对着已经能用的流水线定下来。
7. 没有账号时能测什么
假 HTTP,不需要凭证:
- E2B:
POST /v2/templates、POST /v2/templates/{id}/builds/{buildID}、GET …/status返回ready。断言步骤正文,并断言build: remote时没有调用本地 Docker。 - Cube:
POST /templates→202,然后状态READY。断言image、毫核、探测和仓库字段。 - OpenSandbox:
POST /v1/sandboxes不是 deploy 方法。Deploy 返回镜像引用。Docker 假服务上的POST /v1/templates返回501,这种情况下插件不声明 fsb deploy。 - 容器版:假的模板 list
GET。功能缺失时 deploy 是E8004。 - 安装器:带
template.deploy的清单被今天的允许列表拒绝,允许列表变长后接受。带template.nope的清单始终拒绝。 - 引擎:没有该功能时
POST /v1/templates返回501;假插件先发 SSEprogress再发result。 - CLI:在今天的二进制上,
abx --provider e2b template deploy在 Docker 之前就是E8004。这条测试可以和文档一起落地,且不改变协议。本次改动没有加它,因为当前门闩已经如此,新测试本身是代码改动。
需要真实凭证,不能用假服务宣称:
- 一次达到
ready的 E2B 构建,以及用该 id 创建的沙箱。 - 一次达到
READY的 Cube 任务,以及经 envd 的执行。 - 一台 OpenSandbox 服务器拉到本 CLI 推送的镜像。
- 一个 ACS
SandboxSet,以及针对它名字的创建。 - 极速版:内置提供方挪到
template.deploy后面之后,把现有部署路径再跑一遍。