API接口文档
更新时间: 2025年12月4日
文档简介
本文档提供了 CBS (Cloud Box Service) 边缘计算盒服务的完整 API 接口说明。CBS 服务用于管理和控制运行在边缘设备上的 Android 容器实例,支持实例的创建、启动、停止、配置等全生命周期管理。
快速开始
基础信息
- 服务地址:
http://{ip}:{port} - 默认端口:
18182 - 数据格式: 所有接口均使用 JSON 格式进行数据交互
- 请求方式: 支持 GET 和 POST 两种请求方式
接口分类
本文档包含以下接口分类:
- 主机接口 - 主机硬件信息、系统状态、镜像管理等
- 实例接口 - 实例的创建、启动、停止、删除等生命周期管理
- 代理操作 - 为实例配置网络代理
- 安卓操控接口 - 对 Android 实例进行各种操作(ADB命令、GPS、视频注入等)
- 接口日志 - 接口调用记录和统计
- SSD盘管理 - 存储设备的管理和配置
- 版本更新 - CBS 服务版本更新
使用说明
- 将文档中的
{ip}替换为实际的 CBS 服务主机 IP 地址 - 将文档中的
{port}替换为实际的端口号(默认为 18182) - 将文档中的
{db_id}替换为实际的实例 ID(格式:EDGE + 12位随机字符)
主机接口
主机相关接口
获取主机配置信息
接口说明: 返回设备硬件与基础运行信息。
请求 URL: http://{ip}:{port}/v1/get_hardware_cfg
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/get_hardware_cfg返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"cpuload": "24%",
"cputemp": 38,
"device_id": "b00133052a52c46f",
"hwaddr": "4e:d8:06:98:07:f4",
"ip": "192.168.11.235",
"kernel_version": "1.0.86_marsbox",
"mem_total": "31764",
"mem_use": "5797",
"mmc_total": "25923",
"mmc_use": "819",
"model": "L1",
"os_version": "1.0.1",
"ssd_total": "239280",
"ssd_use": "10333",
"version": "1.0.12.2.1"
}
}失败:
{
"code": 0,
"error": "错误原因"
}获取主机系统信息
接口说明: 返回 CPU 使用率、磁盘/内存占用、温度、swap 等指标。
请求 URL: http://{ip}:{port}/v1/systeminfo
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/systeminfo返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"cpu": 18.6,
"mem_percent": 18.3,
"mem_total": 31764,
"mmc_percent": 3.2,
"mmc_total": 25923,
"ssd_percent": 4.3,
"ssd_total": 239280,
"swap_percent": 0.7,
"swap_total": 4095,
"temperatures": 38
}
}失败:
{
"code": 0,
"error": "错误原因"
}获取主机网络配置
接口说明: 返回主机当前网关、子网掩码和子网段。
请求 URL: http://{ip}:{port}/v1/net_info
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/net_info返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"gateway": "192.168.10.1",
"host_ip": "192.168.11.235",
"netmask": "255.255.254.0",
"subnet": "192.168.10.0/23"
}
}失败:
{
"code": 0,
"error": "错误原因"
}主机心跳检查
接口说明: 检查主机 HTTP/Docker/Ping 可用性。
请求 URL: http://{ip}:{port}/v1/heartbeat
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/heartbeat返回示例:
成功:
{
"code": 200,
"msg": "主机正常",
"data": {
"docker_status": true,
"http_status": true,
"ping_status": true
}
}失败:
{
"code": 0,
"error": "错误原因"
}获取主机镜像列表
接口说明: 返回 docker images 列表的 repository 与 image_id。
请求 URL: http://{ip}:{port}/v1/get_img_list
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/get_img_list返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": [
{
"repository": "armcloud/demo:latest",
"image_id": "sha256:..."
}
]
}失败:
{
"code": 0,
"error": "错误原因"
}清理未使用镜像
接口说明: 清理主机上未使用的 Docker 镜像
请求 URL: http://{ip}:{port}/v1/prune_images
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/prune_images返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"freed_mb": "2957.40",
"host_ip": "192.168.11.235",
"images": [
"vcloud_android13_edge_20251130185425"
]
}
}失败:
{
"code": 0,
"error": "错误原因"
}导入镜像
接口说明: 上传镜像文件到主机并加载镜像
流式返回说明: 接口使用 NDJSON 格式流式返回进度信息(Content-Type: application/x-ndjson),每行一个 JSON 对象。
阶段说明:
- Uploading: 上传中(upload_progress=100%, load_progress=0%)
- Loading: 加载中(upload_progress=100%, load_progress=1-99%)
- Success: 成功(upload_progress=100%, load_progress=100%)
- Failed: 失败(upload_progress=100%, load_progress=0%)
请求 URL: http://{ip}:{port}/v1/import_image
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| file | 是 | file | 镜像文件(.tar.gz 或 .tar 格式) |
请求示例:
POST http://192.168.30.2:18182/v1/import_image请求体: multipart/form-data
- file: (文件)
返回示例:
流式返回(NDJSON 格式,每行一个 JSON 对象):
{"stage":"Uploading","upload_progress":100,"load_progress":0,"message":"文件上传完成: android13.tar.gz (542.15 MB)"}
{"stage":"Loading","upload_progress":100,"load_progress":1,"message":"正在加载镜像到 Docker..."}
{"stage":"Loading","upload_progress":100,"load_progress":2,"message":"正在加载镜像... (2%)"}
{"stage":"Loading","upload_progress":100,"load_progress":3,"message":"正在加载镜像... (3%)"}
...
{"stage":"Success","upload_progress":100,"load_progress":100,"message":"镜像导入成功: vcloud_android13_edge_20250925011125:latest","data":{"host_ip":"192.168.10.20","image_name":"vcloud_android13_edge_20250925011125:latest","file_size":568524800}}失败:
{
"code": 0,
"data": {},
"msg": "文件上传失败: request Content-Type isn't multipart/form-data"
}设置Swap开关
接口说明: 设置主机 swap 分区的状态:1 为开启,0 为关闭。默认为关闭状态;插入 SSD 后支持开启;swap 分区默认大小为 8G(位于 /container_nswc_lv/.swapfile)。
请求 URL: http://{ip}:{port}/v1/swap/{enable}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| enable | 是 | string | 1=开启 0=关闭 |
请求示例:
GET http://192.168.30.2:18182/v1/swap/示例值返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235"
},
"msg": {
"swap_percent": 0,
"swap_total": 8589930496
}
}失败:
{
"code": 0,
"error": "错误原因"
}重启主机
接口说明: 下发后异步重启主机。
请求 URL: http://{ip}:{port}/v1/reboot_for_arm
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/reboot_for_arm返回示例:
成功:
{
"code": 200,
"msg": "rebooting"
}失败:
{
"code": 0,
"error": "错误原因"
}重置主机
接口说明: 销毁容器、清理映射、格式化并挂载数据盘、清理根分区后重启。
请求 URL: http://{ip}:{port}/v1/reset
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/reset返回示例:
成功:
{
"code": 200,
"msg": "resetting and rebooting"
}失败:
{
"code": 0,
"error": "错误原因"
}发现服务状态
接口说明: 返回 UDP 应答器状态。
请求 URL: http://{ip}:{port}/v1/discover
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/v1/discover返回示例:
成功:
{
"code": 200,
"msg": "UDP发现服务状态",
"data": {
"udp_responder": {
"device_id": "b00133052a52c46f",
"friendly_name": "marsbox",
"port": 7678,
"running": true,
"service": "UDP响应器"
}
}
}失败:
{
"code": 0,
"error": "错误原因"
}实例接口
实例生命周期接口
重命名实例
接口说明: 修改 user_name,即云机名称。
请求 URL: http://{ip}:{port}/container_api/v1/rename/{db_id}/{new_user_name}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 实例唯一标识(EDGE + 12位随机字符) |
| new_user_name | 是 | string | 新的 user_name(展示名称,长度2-40) |
请求示例:
GET http://192.168.30.2:18182/container_api/v1/rename/EDGE0A1B2C3D4E5/new_name返回示例:
成功:
{
"code": 200,
"data": {
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235",
"name": "EDGEF58PN1AB43UA",
"old_user_name": "vmos",
"user_name": "test-rename"
},
"msg": "success"
}失败:
{
"code": 202,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "container not found"
}创建实例
接口说明: 创建安卓实例(bridge 网络、沙盒存储、动态端口分配)。
请求 URL: http://{ip}:{port}/container_api/v1/create
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| user_name | 是 | string | 须填,实例用户名,2-36 位数字/字母,支持 _.- |
| count | 否 | int | 可选,批量创建数量,默认 1,最大 16 |
| bool_start | 否 | boolean | 可选,是否立即启动实例,默认 false |
| bool_macvlan | 否 | boolean | 可选,是否启用 macvlan 双网卡模式(bridge+macvlan),默认 false。启用后实例将获得独立的局域网 IP |
| macvlan_network | 否 | string | 可选,macvlan 网络名称,默认 macvlan100。仅在 bool_macvlan=true 时有效 |
| macvlan_start_ip | 否 | string | 可选,macvlan 起始 IP 地址,仅在 bool_macvlan=true 时有效。count=1 时直接使用指定 IP(需 ARP 检测),count>1 时从起始 IP 开始递增分配。例如 192.168.10.100 |
| image_repository | 否 | string | 本地镜像名称(不含tag),默认值为vcloud_android13_edge_20250925011125 |
| resolution | 否 | object | 分辨率配置对象,包含 dpi、fps、height、width 字段 |
| selinux | 否 | boolean | 是否启用 SELinux |
| dns | 否 | array<string> | DNS 服务器列表 |
| adiName | 否 | string | 可选,ADI 模板文件名(需先通过 /v1/import_adi 上传到 /etc/adi/) |
| adiPass | 否 | string | 可选,ADI 解压密码 |
| lon | 否 | float | 可选,经度。例如 121.5 |
| lat | 否 | float | 可选,纬度。例如 31.2 |
| locale | 否 | string | 可选,语言。例如 zh-CN |
| timezone | 否 | string | 可选,时区。例如 Asia/Shanghai |
| country | 否 | string | 可选,随机生成安卓属性使用的国家代码(ISO Alpha-2)。未填写时默认 CN。 |
| bool_gms_disabled | 否 | boolean | 可选,是否在创建容器时禁用GMS,true=禁用,false=不禁用,不传则使用game.info里的值 |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/create请求体:
{
"user_name": "test-001",
"bool_start": false,
"image_repository": "vcloud_android13_edge_20250925011125",
"adiName": "template.zip",
"adiPass": "password",
"resolution": {
"dpi": 560,
"fps": 60,
"height": 3040,
"width": 1440
},
"selinux": false,
"dns": [
"8.8.8.8",
"1.1.1.1"
],
"bool_gms_disabled": false
}返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"host_ip": "192.168.10.102",
"list": [
{
"db_id": "EDGE0A1B2C3D4E5",
"name": "EDGE0A1B2C3D4E5",
"user_name": "test-001",
"status": "creating",
"message": "正在创建中...",
"short_id": "",
"id": "",
"adb": 21000,
"ip": "",
"data": "/container_nswc_lv/EDGE0A1B2C3D4E5/data",
"dns": "8.8.8.8",
"dpi": "560",
"fps": "60",
"height": "3040",
"width": "1440",
"image": "vcloud_android13_edge_20250925011125:latest",
"memory": 3072,
"aosp_version": "13",
"s5": {
"status": 0,
"statusText": "未启动"
},
"state": "creating",
"created": "2025-10-11 12:00:00",
"host_ip": "192.168.10.102"
}
]
}
}失败:
{
"code": 0,
"data": "本地未找到镜像: vcloud_android13_edge_20250925011125:latest",
"msg": "镜像不存在"
}或
{
"code": 2,
"msg": "invalid user_name: length must be 2-36"
}批量启动实例(异步)
请求 URL: http://{ip}:{port}/container_api/v1/run
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | array<string> | 实例ID数组,支持单个或多个实例ID |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/run请求体:
{
"db_ids": [
"dev_0",
"dev_1"
]
}返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"list": [
{
"db_id": "EDGEF58PN1AB43UA",
"name": "EDGEF58PN1AB43UA",
"state": "starting",
"user_name": "test-rename"
}
]
},
"msg": "success"
}失败:
{
"code": 460,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "Another run task is in progress"
}或
{
"code": 1,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "Invalid db_id value detected."
}批量停止实例(异步)
请求 URL: http://{ip}:{port}/container_api/v1/stop
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | array<string> | 实例ID数组,支持单个或多个实例ID |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/stop请求体:
{
"db_ids": [
"deviceId_0_test-001",
"deviceId_1_test-002"
]
}返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"list": [
{
"db_id": "EDGEF58PN1AB43UA",
"name": "EDGEF58PN1AB43UA",
"state": "stopping",
"user_name": "test-rename"
}
]
},
"msg": "success"
}失败:
{
"code": 1,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "Invalid db_id value detected."
}批量重启实例(异步)
请求 URL: http://{ip}:{port}/container_api/v1/reboot
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | array<string> | 实例ID数组,支持单个或多个实例ID |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/reboot请求体:
{
"db_ids": [
"deviceId_0_test-001",
"deviceId_1_test-002"
]
}返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"list": [
{
"db_id": "EDGEF58PN1AB43UA",
"name": "EDGEF58PN1AB43UA",
"state": "rebooting",
"user_name": "test-rename"
}
]
},
"msg": "success"
}失败:
{
"code": 2,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "Some instances are not in the 'running' state"
}或
{
"code": 1,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "Invalid db_id value detected."
}批量重置实例(异步)
请求 URL: http://{ip}:{port}/container_api/v1/reset
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | array<string> | 实例ID数组,支持单个或多个实例ID |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/reset请求体:
{
"db_ids": [
"EDGE0A1...",
"EDGE6F7..."
]
}返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"list": [
{
"db_id": "EDGEF58PN1AB43UA",
"name": "EDGEF58PN1AB43UA",
"state": "rebuilding",
"user_name": "test-rename"
}
]
},
"msg": "success"
}失败:
{
"code": 2,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "Some instances are not in the 'running' state"
}或
{
"code": 1,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "Invalid db_id value detected."
}批量删除实例(异步)
请求 URL: http://{ip}:{port}/container_api/v1/delete
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | array<string> | 实例ID数组,支持单个或多个实例ID |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/delete请求体:
{
"db_ids": [
"EDGE0A1...",
"EDGE6F7..."
]
}返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"list": [
{
"db_id": "EDGEF58PN1AB43UA",
"name": "EDGEF58PN1AB43UA",
"state": "deleting",
"user_name": "test-rename"
}
]
},
"msg": "success"
}失败:
{
"code": 1,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "Invalid db_id value detected."
}升级实例镜像
接口说明: 将指定实例升级到新镜像版本。升级流程:停止容器 → 删除容器 → 使用新镜像重建 → 启动容器。数据会保留。
请求 URL: http://{ip}:{port}/container_api/v1/upgrade_image
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | array<string> | db_id 数组(支持单个或多个) |
| repository | 是 | string | 镜像仓库名(不含tag,默认使用latest) |
| adiName | 否 | string | 可选,ADI 模板文件名(需先通过 /v1/import_adi 上传到 /etc/adi/) |
| adiPass | 否 | string | 可选,ADI 解压密码 |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/upgrade_image请求体:
{
"db_ids": [
"EDGE0A1...",
"EDGE6F7..."
],
"repository": "vcloud_android13_edge_20250925011125",
"adiName": "template.zip",
"adiPass": "password"
}返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"list": [
{
"db_id": "EDGEF58PN1AB43UA",
"name": "EDGEF58PN1AB43UA",
"repository": "vcloud_android15_edge_20251130184807",
"short_id": "1094f35df4f3",
"status": "success",
"user_name": "test-rename"
}
]
},
"msg": "success"
}失败:
{
"code": 0,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "以下实例正在使用目标镜像: EDGEF58PN1AB43UA"
}或
{
"code": 0,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "镜像不存在: test:latest"
}批量一键新机(异步)
接口说明: 仅允许 running 或 stopped。置 state=renewing 后异步执行停机→清数据→启动;保留 db_id 与 user_name。
请求 URL: http://{ip}:{port}/container_api/v1/replace_devinfo
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | array<string> | 实例ID数组,支持单个或多个实例ID |
| adiName | 否 | string | 可选,ADI模板文件名(需先上传到 /etc/adi/) |
| adiPass | 否 | string | 可选,ADI解压密码 |
| country | 否 | string | 可选,随机生成安卓属性时使用的国家代码(ISO Alpha-2),如 CN。未填写时优先根据实例 locale 推断,否则默认 CN。 |
| wipeData | 否 | boolean | 可选,是否清空数据盘并重置 debug_ramdisk,默认 true。false 时仅刷新配置并保留数据。 |
| lon | 否 | float | 可选,经度。例如 121.5 |
| lat | 否 | float | 可选,纬度。例如 31.2 |
| locale | 否 | string | 可选,语言。例如 zh-CN |
| timezone | 否 | string | 可选,时区。例如 Asia/Shanghai |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/replace_devinfo请求体:
{
"db_ids": [
"EDGE0A1...",
"EDGE6F7..."
],
"adiName": "template.zip",
"adiPass": "password",
"country": "CN",
"wipeData": true,
"lon": 121.5,
"lat": 31.2,
"locale": "zh-CN",
"timezone": "Asia/Shanghai"
}返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"list": [
{
"db_id": "EDGEF58PN1AB43UA",
"is_macvlan": false,
"macvlan_ip": "172.17.0.2",
"macvlan_network": "",
"name": "EDGEF58PN1AB43UA",
"state": "renewing",
"user_name": "test-rename"
}
]
},
"msg": "success"
}失败:
{
"code": 1,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "以下实例不存在: EDGEINVALID12345"
}修改实例IP(仅macvlan下)
接口说明: 仅接受 macvlan 模式的实例,修改其 LAN IP。修改前会检查 db_id 是否存在以及 IP 是否已被占用。
请求 URL: http://{ip}:{port}/container_api/v1/set_ip
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 实例唯一标识(EDGE + 12位随机字符) |
| ip | 是 | string | 新的 LAN IP,需处于 macvlan 网段内 |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/set_ip请求体:
{
"db_id": "EDGE0A1B2C3D4E5",
"ip": "192.168.10.120"
}返回示例:
成功:
{
"code": 200,
"data": {
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235"
},
"msg": "success"
}失败:
{
"code": 1004,
"data": {
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235"
},
"msg": "instance is not in macvlan mode"
}或
{
"code": 1001,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "instance not found"
}获取 ADB 连接命令
请求 URL: http://{ip}:{port}/container_api/v1/adb_start/{db_id}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id |
请求示例:
GET http://192.168.30.2:18182/container_api/v1/adb_start/EDGE0A1B2C3D4E5返回示例:
成功:
{
"code": 200,
"msg": "adb connect 192.168.11.235:21000"
}失败:
{
"code": 202,
"msg": "container not found"
}或
{
"code": 0,
"msg": "fail"
}获取指定实例详细信息
请求 URL: http://{ip}:{port}/container_api/v1/get_android_detail/{db_id}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id |
请求示例:
GET http://192.168.30.2:18182/container_api/v1/get_android_detail/EDGE0A1B2C3D4E5返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"adb_port": 21000,
"aosp_version": "15",
"cpuset": "1-7",
"dns": "8.8.8.8",
"dpi": "480",
"fps": "60",
"height": "2414",
"id": "1094f35df4f314a397bca2a5da44720b558792ffb2d77214d4fbf6a6bb771724",
"image": "vcloud_android15_edge_20251130184807:latest",
"ip": "172.17.0.2",
"mac": "02:42:ac:11:00:02",
"memory": 4096,
"name": "EDGEF58PN1AB43UA",
"network": "bridge",
"short_id": "1094f35df4f3",
"status": "running",
"user_name": "EDGEF58PN1AB43UA",
"width": "1080"
}
}失败:
{
"code": 0,
"error": "错误原因"
}获取截图(jpg)
请求 URL: http://{ip}:{port}/container_api/v1/screenshots/{db_id}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id |
请求示例:
GET http://192.168.30.2:18182/container_api/v1/screenshots/EDGE0A1B2C3D4E5返回示例:
成功: 返回JPEG图片二进制数据(Content-Type: image/jpeg)
失败:
{
"code": 200,
"msg": "not running"
}或
{
"code": 202,
"msg": "container not found"
}实例信息查询
接口说明: 查询实例信息,支持自定义参数。
请求 URL: http://{ip}:{port}/container_api/v1/get_db
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| name | 否 | string | 实例名称(可选) |
| fields | 否 | string | 字段列表,逗号分隔(可选) |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/get_db返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"host_ip": "192.168.10.20",
"count": 2,
"list": [
{
"name": "eef543d81720102b_0_test1",
"user_name": "test1",
"state": "running",
"ip": "172.17.0.2",
"dns": [
"8.8.8.8",
"114.114.114.114"
],
"adb": 5555,
"image": "vcloud_android13_edge_20250925011125:latest",
"created": "2025-10-13 10:30:00",
"updated_at": "2025-10-13 10:35:00"
}
]
}
}失败:
{
"code": 0,
"error": "错误原因"
}查询所有容器id
接口说明: 返回所有实例的 db_id/user_name/adb 列表。
请求 URL: http://{ip}:{port}/container_api/v1/list_names
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/container_api/v1/list_names返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"host_ip": "192.168.11.235",
"list": [
{
"adb": 21000,
"db_id": "EDGEF58PN1AB43UA",
"name": "EDGEF58PN1AB43UA",
"state": "running",
"tcp_audio_port": 23000,
"tcp_control_port": 24000,
"tcp_port": 22000,
"user_name": "vmos"
},
{
"adb": 21001,
"db_id": "EDGERWRZ7FU6YWCZ",
"name": "EDGERWRZ7FU6YWCZ",
"state": "stopped",
"tcp_audio_port": 23001,
"tcp_control_port": 24001,
"tcp_port": 22001,
"user_name": "vmos-001"
}
]
}
}失败:
{
"code": 0,
"error": "错误原因"
}克隆实例任务状态
接口说明: 查询克隆实例任务状态
请求 URL: http://{ip}:{port}/container_api/v1/clone_status
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/container_api/v1/clone_status返回示例:
成功:
{
"code": -1,
"data": null,
"msg": "No cloning tasks"
}失败:
{
"code": 0,
"error": "错误原因"
}克隆实例(异步)
接口说明: 克隆安卓实例。count 为克隆数量,最大为 12;db_id 为克隆源机器的 db_id;user_name 是克隆出来的实例名。
请求 URL: http://{ip}:{port}/container_api/v1/clone
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| user_name | 是 | string | 必选,克隆出来的实例名 |
| db_id | 是 | string | 必选,被克隆的容器 db_id |
| count | 是 | int | 必选,克隆数量,最大为 12 |
| update_prop | 否 | boolean | 可选,是否在克隆完成后自动刷新安卓属性,默认 false。true 时按源实例 country 生成随机 androidProp。 |
请求示例:
POST http://192.168.30.2:18182/container_api/v1/clone请求体:
{
"user_name": "test-001",
"db_id": "EDGE0A1B2C3D4E5",
"count": 1,
"update_prop": true
}返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "cloning is in progress..."
}失败:
{
"code": 202,
"data": {
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235"
},
"msg": "被克隆的云机未关机,请关闭云机后再进行克隆."
}或
{
"code": 202,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "container not found"
}代理操作
代理设置和管理
代理设置
接口说明: 为指定容器实例设置代理配置。
请求 URL: http://{ip}:{port}/android_api/v1/proxy_set/{db_id}
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 实例唯一标识(EDGE + 12位随机字符,如 EDGE0A1B2C3D4E5) |
| ip | 是 | string | 代理服务器 IP 或域名 |
| port | 是 | int | 代理端口号 |
| account | 否 | string | 用户名 / 账号 |
| password | 否 | string | 密码,shadowsocks 时用作密钥 |
| proxyName | 否 | string | 协议类型,例如 vpn / socks5 |
| udpDisabled | 否 | boolean | 是否禁用 UDP |
| dnsOverProxyDisabled | 否 | boolean | 是否禁用 DNS 走代理 |
请求示例:
POST http://192.168.30.2:18182/android_api/v1/proxy_set/EDGE0A1B2C3D4E5请求体:
{
"ip": "1.2.3.4",
"port": 2222,
"account": "demo",
"password": "demo123",
"proxyName": "vpn",
"udpDisabled": false,
"dnsOverProxyDisabled": false
}返回示例:
成功:
{
"code": 200,
"data": {
"container_ip": "172.17.0.2",
"host_ip": "192.168.11.235",
"name": "EDGEF58PN1AB43UA",
"proxy_info": {
"enable": true,
"ip": "1.2.3.4",
"port": 2222,
"proxyName": "socks5"
},
"user_name": "test-rename"
},
"msg": "成功"
}失败:
{
"code": 0,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "实例不存在: EDGEINVALID12345"
}代理关闭
接口说明: 关闭指定容器实例的 SOCKS5 代理。CBS 会将请求转发到容器内的 HTTP 服务(18183 端口),并自动清理数据库中的代理配置信息。
请求 URL: http://{ip}:{port}/android_api/v1/proxy_stop/{db_id}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 实例唯一标识(EDGE + 12位随机字符) |
请求示例:
GET http://192.168.30.2:18182/android_api/v1/proxy_stop/EDGE0A1B2C3D4E5返回示例:
成功:
{
"code": 200,
"data": {
"enable": false,
"host_ip": "192.168.11.235",
"name": "EDGEF58PN1AB43UA"
},
"msg": "代理已关闭"
}失败:
{
"code": 0,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "实例不存在: EDGEINVALID12345"
}代理查询
接口说明: 查询指定容器实例的代理生效后的真实 IP 和地理位置信息。CBS 会将请求转发到容器内的 HTTP 服务(18183 端口)。
请求 URL: http://{ip}:{port}/android_api/v1/proxy_get/{db_id}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 实例唯一标识(EDGE + 12位随机字符) |
请求示例:
GET http://192.168.30.2:18182/android_api/v1/proxy_get/EDGE0A1B2C3D4E5返回示例:
成功:
{
"code": 200,
"data": {
"container_ip": "172.17.0.2",
"host_ip": "192.168.11.235",
"name": "EDGEF58PN1AB43UA",
"proxy_config": null,
"user_name": "test-rename"
},
"msg": "未设置代理"
}失败:
{
"code": 0,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "实例不存在: EDGEINVALID12345"
}安卓操控接口
Android 系统操控相关接口
关闭当前窗口应用
接口说明: 自动获取容器内当前前台应用的包名,并使用 am force-stop 命令强制关闭该应用。
请求 URL: http://{ip}:{port}/android_api/v1/stop_front_app/{db_id}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 实例唯一标识(EDGE + 12位随机字符) |
请求示例:
GET http://192.168.30.2:18182/android_api/v1/stop_front_app/EDGE0A1B2C3D4E5返回示例:
成功:
{
"code": 200,
"data": {
"container_name": "EDGEF58PN1AB43UA",
"package_name": "com.android.armlauncher3"
},
"msg": "当前为桌面,未执行关闭"
}失败:
{
"code": 201,
"msg": "实例 EDGEINVALID12345 不存在"
}执行ADB命令
接口说明: 在容器内同步执行自定义 ADB Shell 命令。命令会在后台执行,接口立即返回,不阻塞。执行结果会记录在日志中。
请求 URL: http://{ip}:{port}/android_api/v1/shell/{db_id}
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 实例唯一标识(EDGE + 12位随机字符) |
| cmd | 是 | string | 要执行的 shell 命令 |
请求示例:
POST http://192.168.30.2:18182/android_api/v1/shell/EDGE0A1B2C3D4E5返回示例:
成功:
{
"code": 200,
"data": {
"cmd": "echo test",
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235",
"message": "test"
},
"msg": "success"
}失败:
{
"code": 201,
"msg": "实例 EDGEINVALID12345 不存在"
}根据IP获取经纬度
接口说明: 根据实例或代理IP查询经纬度;若提供query.ip则优先使用。若实例启用代理,优先使用ProxyRealIP,其次ProxyIP;否则使用实例IP(私网IP将返回不可定位)。
请求 URL: http://{ip}:{port}/android_api/v1/ip_geo/{db_id}?ip={ip}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id |
| ip | 否 | string | 可选,覆盖查询的IP |
请求示例:
GET http://192.168.30.2:18182/android_api/v1/ip_geo/EDGE0A1B2C3D4E5?ip=示例值返回示例:
成功:
{
"code": 200,
"data": {
"city": "Mountain View",
"country": "US",
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235",
"ip": "8.8.8.8",
"lat": 37.4056,
"lon": -122.0775,
"name": "EDGEF58PN1AB43UA",
"region": "California",
"source": "ipinfo.io"
},
"msg": "success"
}失败:
{
"code": 0,
"data": {
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235",
"ip": "172.17.0.2",
"name": "EDGEF58PN1AB43UA"
},
"msg": "私网IP无法定位,请配置代理或提供公网IP"
}批量安装APK
接口说明: 通过上传APK文件的方式批量安装到指定的安卓容器。文件将先上传到主机/tmp目录,然后批量拷贝到容器内并执行 pm install -r 安装。
请求 URL: http://{ip}:{port}/android_api/v1/upload_file_android_batch
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | string | 实例ID列表,多个用逗号分隔,如 EDGE123,EDGE456 |
| file | 是 | file | APK文件 |
请求示例:
POST http://192.168.30.2:18182/android_api/v1/upload_file_android_batch请求体: multipart/form-data
db_ids: 实例ID列表,多个用逗号分隔,如 EDGE123,EDGE456
file: (文件)
返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"results": {
"EDGE0A1B2C3D4E5": "安装成功",
"EDGE6F7...": "安装失败: Failure [INSTALL_FAILED_ALREADY_EXISTS]"
}
},
"msg": "执行完成"
}失败:
{
"code": 201,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "缺少文件参数 file"
}批量上传文件
接口说明: 通过上传本地文件的方式批量复制至实例指定目录。path 参数为可选,默认拷贝到 /storage/emulated/0/Download,若指定目录需提前存在,不存在时提示错误。
请求 URL: http://{ip}:{port}/android_api/v1/upload_file_android_upload
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_ids | 是 | string | 实例ID列表,多个用逗号分隔,如 EDGE123,EDGE456 |
| file | 是 | file | 上传的文件 |
| path | 否 | string | 可选,目标目录,默认 /storage/emulated/0/Download |
| 请求示例: |
POST http://192.168.30.2:18182/android_api/v1/upload_file_android_upload请求体: multipart/form-data
db_ids: 实例ID列表,多个用逗号分隔,如 EDGE123,EDGE456
file: (文件)
path: 可选,目标目录,默认 /storage/emulated/0/Download
返回示例:
成功:
{
"code": 200,
"data": {
"host_ip": "192.168.11.235",
"results": {
"EDGE0A1B2C3D4E5": "上传成功",
"EDGE6F7...": "目录不存在: /data/custom/path"
}
},
"msg": "执行完成"
}失败:
{
"code": 201,
"data": {
"host_ip": "192.168.11.235"
},
"msg": "缺少文件参数 file"
}设置实例经纬度
接口说明: 参考 CloudGameServer 的 gpsInjectInfo。经纬度必填。CBS 将参数转发至容器 http://{container_ip}:18183/api/gpsInjectInfo。
请求 URL: http://{ip}:{port}/android_api/v1/gps_inject/{db_id}
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id(路径参数) |
| longitude | 是 | float | 经度 |
| latitude | 是 | float | 纬度 |
| altitude | 否 | float | 海拔高度 |
| speed | 否 | float | 速度 |
| bearing | 否 | float | 方向角 |
| horizontalAccuracyMeters | 否 | float | 水平精度(米) |
请求示例:
POST http://192.168.30.2:18182/android_api/v1/gps_inject/EDGE0A1B2C3D4E5请求体:
{
"longitude": 116.397455,
"latitude": 39.909187,
"altitude": 8,
"speed": 8,
"bearing": 0,
"horizontalAccuracyMeters": 0.1
}返回示例:
成功:
{
"code": 200,
"data": {
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235",
"name": "EDGEF58PN1AB43UA"
},
"msg": "成功"
}失败:
{
"code": 0,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "实例不存在: EDGEINVALID12345"
}设置视频注入
接口说明: 转发到容器 /api/injectVideo。Body: { 'url': 'https://xxx.mp4' },CBS 会构造 injectSwitch=true, injectLoop=true, injectUrl=url 并转发。
请求 URL: http://{ip}:{port}/android_api/v1/video_inject/{db_id}
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id(路径参数) |
| url | 是 | string | 视频URL地址,如 https://example.com/demo.mp4 |
请求示例:
POST http://192.168.30.2:18182/android_api/v1/video_inject/EDGE0A1B2C3D4E5请求体:
{
"url": "https://example.com/demo.mp4"
}返回示例:
成功:
{
"code": 200,
"cost": 1566,
"data": "视频注入已启动",
"message": "成功"
}失败:
{
"code": 500,
"cost": 1566,
"message": "视频注入失败: 视频下载失败: response failed: 404 "
}关闭视频注入
接口说明: 转发到容器 /api/injectVideo,payload: { injectSwitch:false, injectLoop:false, injectUrl:'' }。
请求 URL: http://{ip}:{port}/android_api/v1/video_inject_off/{db_id}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id |
请求示例:
GET http://192.168.30.2:18182/android_api/v1/video_inject_off/EDGE0A1B2C3D4E5返回示例:
成功:
{
"code": 200,
"cost": 1,
"data": "停止注入成功",
"message": "成功"
}失败:
{
"code": 0,
"error": "错误原因"
}设置实例时区
接口说明: 转发到容器 /api/updateTimeZone。Body: { 'timeZone': 'Asia/Shanghai' }
请求 URL: http://{ip}:{port}/android_api/v1/timezone_set/{db_id}
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id |
| timeZone | 是 | string | 时区,如 Asia/Shanghai |
请求示例:
POST http://192.168.30.2:18182/android_api/v1/timezone_set/EDGE0A1B2C3D4E5请求体:
{
"timeZone": "Asia/Shanghai"
}返回示例:
失败:
{
"code": 0,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "实例不存在: EDGEINVALID12345"
}设置实例语言
接口说明: 转发到容器 /api/updateLanguage。Body: { 'country': 'CN', 'language': 'zh' }
请求 URL: http://{ip}:{port}/android_api/v1/language_set/{db_id}
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 容器id(路径参数) |
| country | 是 | string | 国家代码,如 CN |
| language | 是 | string | 语言代码,如 zh |
请求示例:
POST http://192.168.30.2:18182/android_api/v1/language_set/EDGE0A1B2C3D4E5请求体:
{
"country": "CN",
"language": "zh"
}返回示例:
失败:
{
"code": 0,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "实例不存在: EDGEINVALID12345"
}查询实例国家、语言、时区
接口说明: 从容器内通过 getprop 获取 persist.sys.timezone/persist.sys.locale/persist.sys.country,只支持 running 状态实例。
请求 URL: http://{ip}:{port}/android_api/v1/get_timezone_locale/{db_id}
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| db_id | 是 | string | 实例唯一标识(EDGE + 12位随机字符) |
请求示例:
GET http://192.168.30.2:18182/android_api/v1/get_timezone_locale/EDGE0A1B2C3D4E5返回示例:
成功:
{
"code": 200,
"data": {
"country": "HK",
"db_id": "EDGEF58PN1AB43UA",
"host_ip": "192.168.11.235",
"locale": "zh-CN",
"timezone": "Asia/Shanghai",
"user_name": "test-rename"
},
"msg": "查询成功"
}失败:
{
"code": 0,
"data": {
"db_id": "EDGEINVALID12345",
"host_ip": "192.168.11.235"
},
"msg": "实例不存在: EDGEINVALID12345"
}接口日志
接口执行记录与统计(最近20条、导出、成功率)
查询最近接口日志
接口说明: 返回最近20条接口执行记录(/var/log/interface.log)
请求 URL: http://{ip}:{port}/interface_logs/recent
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/interface_logs/recent返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"count": 20,
"list": [
{
"time": "2025-11-30T21:29:46+08:00",
"method": "执行adb命令",
"status_code": 200,
"success": true
}
]
}
}失败:
{
"code": 0,
"error": "错误原因"
}显示日志详情
接口说明: 显示日志详情
请求 URL: http://{ip}:{port}/interface_logs/detail
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/interface_logs/detail返回示例:
失败:
{
"code": 0,
"error": "错误原因"
}接口成功率查询
接口说明: 统计各接口执行次数与成功率
请求 URL: http://{ip}:{port}/interface_logs/stats
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/interface_logs/stats返回示例:
成功:
{
"code": 200,
"msg": "success",
"data": {
"count": 4,
"list": [
{
"key": "执行adb命令",
"total": 20,
"success": 20,
"success_rate": "100%"
}
]
}
}失败:
{
"code": 2,
"msg": "missing or unconfirmed"
}SSD盘管理
本地存储(SSD)管理
存储状态
接口说明: 返回启动时扫描的存储状态:trial(试用,无SSD)、new_ssd(发现新SSD,需操作)、ssd(已登记并挂载)。
请求 URL: http://{ip}:{port}/storage/status
请求方式: GET
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无 |
请求示例:
GET http://192.168.30.2:18182/storage/status返回示例:
成功:
{
"mode": "ssd",
"mounted": true,
"root": "/container_nswc_lv",
"device": {
"path": "/dev/nvme0n1p1",
"model": "SAMSUNG MZVL4256HBJD-00BH1",
"serial": "S6B6NU0W808341",
"size": "238.5G",
"fstype": "ext4",
"uuid": "60a716a0-7fe4-49fb-9637-b28b61879e08",
"mounted": true
},
"action_required": false
}失败:
{
"code": 2,
"msg": "missing or unconfirmed"
}格式化为数据盘并挂载
接口说明: 将指定设备格式化为 ext4 并挂载至 /container_nswc_lv,写入 fstab(UUID)。
请求 URL: http://{ip}:{port}/storage/format
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| device | 是 | string | 如 /dev/nvme0n1 或其分区 |
| confirm | 是 | boolean | 确认操作,必须为 true |
请求示例:
POST http://192.168.30.2:18182/storage/format请求体:
{
"device": "/dev/nvme0n1",
"confirm": true
}返回示例:
成功:
{
"code": 200,
"msg": "success"
}失败:
{
"code": 2,
"msg": "missing or unconfirmed"
}导入已有数据盘并挂载
接口说明: 不格式化,直接将指定设备挂载为 /container_nswc_lv。
请求 URL: http://{ip}:{port}/storage/import
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| device | 是 | string | 设备路径,如 /dev/nvme0n1 |
| confirm | 是 | boolean | 确认操作,必须为 true |
请求示例:
POST http://192.168.30.2:18182/storage/import请求体:
{
"device": "/dev/nvme0n1",
"confirm": true
}返回示例:
成功:
{
"code": 200,
"msg": "success"
}失败:
{
"code": 2,
"msg": "missing or unconfirmed"
}版本更新
CBS 版本更新
CBS版本更新
接口说明: 上传 CBS 可执行文件并更新服务,更新后请刷新本页面。
请求 URL: http://{ip}:{port}/v1/update_cbs
请求方式: POST
请求参数:
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| file | 是 | file | CBS 可执行文件(文件名必须为 cbs_go_edge_版本号 格式;支持无后缀或 .cbs,不支持 .exe) |
| 请求示例: |
POST http://192.168.30.2:18182/v1/update_cbs请求体: multipart/form-data
- file: (文件)
返回示例:
成功:
{
"code": 200,
"msg": "CBS 更新成功",
"data": {
"host_ip": "192.168.10.20",
"current_version": "1.0.10.13.1"
}
}失败:
{
"code": 0,
"data": {
"current_version": "1.0.12.2.1",
"host_ip": "192.168.11.235"
},
"msg": "文件上传失败: request Content-Type isn't multipart/form-data"
}通用说明
响应码说明
| 响应码 | 说明 | 使用场景 |
|---|---|---|
| 200 | 请求成功 | 接口调用成功,操作正常完成 |
| 201 | 特殊参数错误 | 文件上传格式错误、Content-Type 错误等特殊参数验证失败 |
| 0 | 操作失败 | 大部分失败场景,如实例不存在、镜像不存在、操作失败等 |
| 1 | 参数错误 | 参数格式错误、必填参数缺失、参数值无效等 |
| 2 | 状态错误 | 实例状态不符合操作要求(如需要 running 状态但实例为 stopped) |
| 202 | 资源不存在 | 容器不存在、资源未找到等 |
| 460 | 操作冲突 | 另一个相同类型的任务正在进行中 |
| 500 | 服务器错误 | 服务器内部错误,如视频下载失败等 |
| 1001 | 实例不存在 | 指定的实例 ID 不存在 |
| 1004 | 模式不匹配 | 实例不在 macvlan 模式下,无法执行相关操作 |
注意事项
基础说明
- 数据格式: 所有接口均返回 JSON 格式数据
- 地址替换: 请求参数中的
{ip}和{port}需要替换为实际的CBS服务地址和端口 - 实例ID格式: 路径参数中的
{db_id}为实例唯一标识,格式为EDGE+ 12位随机字符(如:EDGEF58PN1AB43UA) - 批量操作: 批量操作接口支持同时操作多个实例,通过
db_ids数组传递
异步操作说明
部分接口为异步操作,接口调用后会立即返回,实际操作在后台执行。异步操作接口包括:
- 创建实例 (
/container_api/v1/create) - 批量启动实例 (
/container_api/v1/run) - 批量停止实例 (
/container_api/v1/stop) - 批量重启实例 (
/container_api/v1/reboot) - 批量重置实例 (
/container_api/v1/reset) - 批量删除实例 (
/container_api/v1/delete) - 升级实例镜像 (
/container_api/v1/upgrade_image) - 批量一键新机 (
/container_api/v1/replace_devinfo) - 克隆实例 (
/container_api/v1/clone)
异步操作返回后,可通过查询接口(如 /container_api/v1/get_db)查看实例状态变化。
实例状态说明
实例可能处于以下状态:
creating- 正在创建中starting- 正在启动中running- 运行中stopping- 正在停止中stopped- 已停止rebooting- 正在重启中rebuilding- 正在重置中renewing- 正在一键新机中deleting- 正在删除中
重要: 部分接口需要实例处于特定状态才能执行:
- 需要
running状态的接口:GPS注入、视频注入、执行ADB命令、查询时区语言等 - 需要
stopped状态的接口:克隆实例(源实例必须停止)
文件上传说明
文件上传接口需要使用 multipart/form-data 格式:
- 导入镜像 (
/v1/import_image): 支持.tar.gz或.tar格式 - 批量安装APK (
/android_api/v1/upload_file_android_batch): 支持.apk文件 - 批量上传文件 (
/android_api/v1/upload_file_android_upload): 支持任意文件 - CBS版本更新 (
/v1/update_cbs): 文件名必须为cbs_go_edge_版本号格式,支持无后缀或.cbs,不支持.exe
错误处理建议
- 检查响应码: 首先检查返回的
code字段,判断操作是否成功 - 查看错误信息:
msg或error字段包含具体的错误原因 - 状态检查: 对于异步操作,需要轮询查询接口确认操作完成
- 参数验证: 确保所有必填参数都已提供且格式正确
- 实例状态: 确认实例处于操作所需的状态
常见问题
Q: 如何获取实例列表?
A: 使用 /container_api/v1/list_names 获取所有实例的基本信息,或使用 /container_api/v1/get_db 获取详细信息。
Q: 如何判断异步操作是否完成?
A: 通过 /container_api/v1/get_db 接口查询实例的 state 字段,确认状态是否已变为目标状态。
Q: 实例创建后如何连接?
A: 使用 /container_api/v1/adb_start/{db_id} 获取 ADB 连接命令,然后使用 adb connect 命令连接。
Q: 如何批量操作多个实例?
A: 在请求的 db_ids 数组中传入多个实例ID即可,如:{"db_ids": ["EDGE001", "EDGE002", "EDGE003"]}
Q: 文件上传失败怎么办?
A: 检查请求的 Content-Type 是否为 multipart/form-data,确保文件格式正确且文件大小在允许范围内。
Q: 如何查看接口调用记录?
A: 使用 /interface_logs/recent 查看最近20条接口调用记录,使用 /interface_logs/stats 查看接口成功率统计。
