跳到主要内容
版本:1.11.x

将沙箱提交为镜像

ROCK 可以将运行中的沙箱容器提交为 Docker 镜像,并将镜像推送到 Registry。对于体积较大的沙箱,docker commitdocker push 可能耗时较长,因此异步接口会立即返回。调用方使用 sandbox ID 轮询状态,直到任务进入终态。

异步流程如下:

POST /commit          -> RUNNING
GET /commit/{id} -> RUNNING
GET /commit/{id} -> SUCCEEDED 或 FAILED
export ROCK_API_URL="https://xrl.alibaba-inc.com/apis/envs/sandbox/v1"

使用前提

  • Registry 账号必须具有目标镜像的推送权限,且沙箱网络环境能够访问。

HTTP API

发起 commit

POST $ROCK_API_URL/commit
Content-Type: application/json

请求参数:

字段类型必填说明
sandbox_idstringsandbox ID,同时也是 Docker 容器名。
image_tagstring完整的目标镜像名称,例如 registry.example.com/team/app:v1
usernamestringRegistry 用户名。
passwordstringRegistry 密码。直接传原始密码,无需进行 Base64 编码。
curl -sS -X POST "$ROCK_API_URL/commit" \
-H "Content-Type: application/json" \
-d '{
"sandbox_id": "sandbox-123",
"image_tag": "registry.example.com/team/app:v1",
"username": "registry-user",
"password": "registry-password"
}'

任务成功受理后返回 RUNNING

{
"status": "Success",
"message": null,
"error": null,
"result": {
"sandbox_id": "sandbox-123",
"image_tag": "registry.example.com/team/app:v1",
"phase": "RUNNING",
"started_at": "2026-07-22T10:30:00+08:00",
"completed_at": null,
"exit_code": null,
"failed_stage": null,
"error_code": null,
"error_message": null
}
}

查询 commit 状态

GET $ROCK_API_URL/commit/{sandbox_id}
curl -sS "$ROCK_API_URL/commit/sandbox-123"

建议每隔几秒轮询一次,直到 result.phase 变为 SUCCEEDEDFAILED。成功结果示例:

{
"status": "Success",
"result": {
"sandbox_id": "sandbox-123",
"image_tag": "registry.example.com/team/app:v1",
"phase": "SUCCEEDED",
"started_at": "2026-07-22T10:30:00+08:00",
"completed_at": "2026-07-22T10:36:42+08:00",
"exit_code": 0,
"failed_stage": null,
"error_code": null,
"error_message": null
}
}

如果后台操作失败,请求本身仍然成功,但任务状态为 FAILED

{
"status": "Success",
"result": {
"sandbox_id": "sandbox-123",
"image_tag": "registry.example.com/team/app:v1",
"phase": "FAILED",
"started_at": "2026-07-22T10:30:00+08:00",
"completed_at": "2026-07-22T10:30:03+08:00",
"exit_code": 11,
"failed_stage": "login",
"error_code": "LOGIN_FAILED",
"error_message": "Error response from daemon: ..."
}
}

状态字段

字段说明
phaseRUNNINGSUCCEEDEDFAILED
started_atworker 接受任务的时间。
completed_at任务结束时间,仅终态任务存在。
exit_code成功时为 0,失败时为非零值或 -1
failed_stage失败步骤,例如 logincommitpushsupervisor
error_code供程序判断的错误码。
error_message供排障使用的可读日志末尾内容。

常见任务错误包括 LOGIN_FAILEDCOMMIT_FAILEDPUSH_FAILEDTIMEOUTPROCESS_LOSTSANDBOX_CONTAINER_NOT_FOUNDCOMMIT_CONFLICTSTATUS_NOT_FOUNDWORKER_UNREACHABLE 等错误属于请求级失败,顶层 status 会返回 Failed

重复请求

  • 同一个 sandbox 正在提交相同的 image_tag 时,再次调用 POST /commit 会返回已有的 RUNNING 任务,不会启动第二个进程。
  • 同一个 sandbox 正在提交不同的 image_tag 时,请求会以 COMMIT_CONFLICT 失败。
  • 任务进入 SUCCEEDEDFAILED 后,再次调用 POST /commit 会启动新任务,并覆盖该 sandbox 的上一次状态。

Python SDK

当调用方需要等待最终结果时,使用 commit()。该方法内部调用 commit_async(),并轮询 get_commit_status(),直到任务进入 SUCCEEDEDFAILED

参数默认值说明
timeout180发起任务和轮询状态的总超时时间,超时后抛出 TimeoutError
interval2两次状态查询之间的等待时间。

超时只会停止 SDK 端的等待,不会取消 worker 上已经运行的 commit 任务。之后仍可调用 get_commit_status() 查询该任务。

调用前,Sandbox 对象应已启动。

from rock.actions import CommitPhase


async def commit_and_wait(sandbox):
status = await sandbox.commit(
image_tag="registry.example.com/team/app:v1",
username="registry-user",
password="registry-password",
timeout=180,
interval=2,
)
if status is None:
raise RuntimeError("sandbox_id 未设置")

if status.phase == CommitPhase.FAILED:
raise RuntimeError(
f"commit 失败: code={status.error_code}, "
f"stage={status.failed_stage}, message={status.error_message}"
)

print(f"镜像推送成功: {status.image_tag}")

当调用方不希望等待,或需要自行控制轮询逻辑时,可直接使用 commit_async()。该方法返回任务的初始状态,后续状态通过 get_commit_status() 查询。

TypeScript SDK

使用 commit() 发起任务并等待最终状态。该方法内部调用 commitAsync(),并轮询 getCommitStatus()timeoutinterval 参数的单位为秒,默认值分别为 1802

import { CommitPhase } from 'rl-rock';

async function commitAndWait(sandbox) {
const status = await sandbox.commit(
'registry.example.com/team/app:v1',
'registry-user',
'registry-password',
180,
2
);
if (!status) {
throw new Error('sandbox_id 未设置');
}

if (status.phase === CommitPhase.FAILED) {
throw new Error(
`commit 失败: code=${status.errorCode}, ` +
`stage=${status.failedStage}, message=${status.errorMessage}`
);
}

console.log(`镜像推送成功: ${status.imageTag}`);
}

超时只会停止 SDK 端的等待,不会取消 worker 上已经运行的任务。调用方需要自行控制轮询时可使用 commitAsync(),之后通过 getCommitStatus() 查询任务状态。