Skip to content

AI App 安装与服务部署进度 API

本文说明 AI App 手动安装、设备侧服务部署、流式进度,以及按 serviceId 查询最近部署状态的接口。

如需联调测试流程,可参考项目仓库中的部署进度测试文档。

1. 基础约定

  • AI Pod 对外域名:https://<subdomain>.<box-domain>
  • subdomain 从应用的 lzc-manifest.yml 中读取,当前默认是 ai
  • box-domain 优先通过 lzc-cli box default 获取;拿不到时默认使用 13gxg.heiyu.space

平台侧接口基准路径:

  • https://<subdomain>.<box-domain>/backend/aiapps
  • https://<subdomain>.<box-domain>/backend/services

设备侧接口基准路径:

  • http://<device-ip>:<device-port>/v1/service

2. AI App 手动安装

2.1 POST /backend/aiapps/install/stream

用途:

  • 上传一个 AI App ZIP
  • 完成注册
  • 如果包内带 pkg/ai-pod-service/docker-compose.yml,继续触发设备部署
  • 通过 SSE 返回安装进度

请求:

  • Method: POST
  • Content-Type: multipart/form-data
  • 必填字段:file

返回:

  • Content-Type: text/event-stream
  • 事件名:progress

事件结构:

json
{
  "stage": "pulling",
  "status": "downloading",
  "progress": 37,
  "message": "registry.lazycat.cloud/demo/app:latest: Downloading",
  "pkgId": "demo-app",
  "serviceId": "demo-app",
  "currentImage": "registry.lazycat.cloud/demo/app:latest",
  "currentLayer": "sha256:abcd",
  "current": 5242880,
  "total": 10485760,
  "error": ""
}

说明:

  • 本地包处理阶段仍会发送 upload_savedunzippingvalidatingregistering 等状态消息。
  • 这些阶段的 progress 固定为 0,不计入安装进度条。
  • 真正推进安装进度的是服务部署阶段:
    • pulling: 0-80
    • starting: 85
    • waiting: 95
    • completed: 100
    • failed: 保持失败前进度
  • 如果 AI App 没有可部署服务,则直接返回:
    • stage=completed
    • progress=100
    • message=installed without deployable service

典型返回:

text
event:progress
data:{"stage":"registering","progress":0,"message":"registering ai app","pkgId":"demo-app"}

event:progress
data:{"stage":"pulling","status":"downloading","progress":31,"message":"registry.lazycat.cloud/demo/app:latest: Downloading","pkgId":"demo-app","serviceId":"demo-app","currentImage":"registry.lazycat.cloud/demo/app:latest","currentLayer":"sha256:abcd","current":5242880,"total":10485760}

event:progress
data:{"stage":"starting","status":"starting","progress":85,"message":"starting service","pkgId":"demo-app","serviceId":"demo-app"}

event:progress
data:{"stage":"waiting","status":"waiting","progress":95,"message":"waiting for service health","pkgId":"demo-app","serviceId":"demo-app"}

event:progress
data:{"stage":"completed","status":"complete","progress":100,"message":"service deployed","pkgId":"demo-app","serviceId":"demo-app"}

失败示例:

text
event:progress
data:{"stage":"failed","status":"error","progress":42,"message":"pull images failed","pkgId":"demo-app","serviceId":"demo-app","error":"pull access denied"}

2.2 DELETE /backend/aiapps/apps/:pkgId

用途:

  • 删除手动安装的 AI App
  • 同步删除对应服务目录、缓存目录和镜像

返回:

json
{"removed":true,"pkgId":"demo-app"}

2.3 GET /backend/aiapps/apps

用途:

  • 查看当前 AI App 列表

2.4 GET /backend/aiapps/installed/:pkgId

用途:

  • 查看指定 pkgId 是否已经注册到 AI App store

返回:

json
{"installed":true}

3. 平台侧服务接口

3.1 GET /backend/services/progress?serialNumber=<sn>&serviceId=<serviceId>

用途:

  • 查询某台设备上指定服务最近一次部署进度
  • 适用于自动触发部署场景,或手动安装过程中断线后恢复查看

返回结构:

json
{
  "serviceId": "demo-app",
  "stage": "pulling",
  "status": "extracting",
  "progress": 56,
  "message": "registry.lazycat.cloud/demo/app:latest: Extracting",
  "currentImage": "registry.lazycat.cloud/demo/app:latest",
  "currentLayer": "sha256:abcd",
  "current": 7340032,
  "total": 10485760,
  "startedAt": 1742880000,
  "updatedAt": 1742880012,
  "finishedAt": 0,
  "error": ""
}

空闲态返回:

json
{
  "serviceId": "demo-app",
  "stage": "idle",
  "progress": 0,
  "message": "deployment not started"
}

3.2 现有平台侧接口

  • GET /backend/services/list?serialNumber=<sn>
  • GET /backend/services/start?serialNumber=<sn>&serviceId=<serviceId>
  • GET /backend/services/stop?serialNumber=<sn>&serviceId=<serviceId>
  • GET /backend/services/delete?serialNumber=<sn>&serviceId=<serviceId>
  • GET /backend/services/log?serialNumber=<sn>&serviceId=<serviceId>

说明:

  • start 是同步触发,不返回流式进度
  • 自动触发部署和 start 都会持续更新 serviceId 对应的最近部署状态
  • 若需要实时进度,优先使用 AI App 安装流或设备侧 /service/start/stream

4. 设备侧服务接口

4.1 POST /v1/service/start

用途:

  • 触发一次同步部署
  • 内部仍会更新最近部署状态

请求字段:

  • file: service zip
  • serviceId
  • dirOverWrite: true|false
  • forceRecreate: true|false
  • extraEnv[KEY]=VALUE: 可选

4.2 POST /v1/service/start/stream

用途:

  • 触发一次流式部署
  • /v1/service/start 使用同一套底层部署逻辑
  • 只是额外把进度通过 SSE 返回

返回:

  • Content-Type: text/event-stream
  • 事件名:progress
  • 数据结构与 backend.ServiceDeployStatus 一致

4.3 GET /v1/service/progress?serviceId=<serviceId>

用途:

  • 查询该服务最近一次部署状态

4.4 GET /v1/service/log?serviceId=<serviceId>

用途:

  • 持续查看服务日志

4.5 GET /v1/service/installed

用途:

  • 查看设备上当前已安装服务及 docker-compose.yml 摘要信息

5. 部署进度语义

统一状态字段:

  • stage: 粗粒度阶段
  • status: 细粒度状态
  • progress: 0-100
  • message: 人类可读消息

当前阶段定义:

stageprogress含义
idle0当前没有部署记录
prepare0开始部署,准备目录、解压、写 .env
pulling0-80拉取 compose 镜像
starting85执行 docker-compose up -d --wait
waiting95容器已拉起,等待健康检查或 --wait 完成
completed100部署成功
failed保持当前值部署失败,错误见 error

pulling.status 目前可能出现:

  • prepare
  • preparing
  • waiting
  • downloading
  • download_complete
  • extracting
  • verifying
  • already_exists
  • complete

说明:

  • pulling 的百分比来自 Docker Engine ImagePull 的结构化字节进度,不再依赖 docker-compose pull PTY 文本。
  • 多镜像场景下,按镜像平均权重汇总成整体 0-80 进度。
  • startingwaiting 目前是阶段型进度,不是容器级精确百分比。
  • 系统只保留每个 serviceId 最近一次部署状态。

6. 调用示例

6.1 手动安装 AI App 并查看流式进度

bash
curl --no-buffer \
  -F "file=@./demo-app.zip" \
  "https://ai.13gxg.heiyu.space/backend/aiapps/install/stream"

6.2 查询某个服务最近部署状态

bash
curl \
  "https://ai.13gxg.heiyu.space/backend/services/progress?serialNumber=<sn>&serviceId=demo-app"

6.3 直接调用设备侧流式部署接口

bash
curl --no-buffer \
  -F "file=@./demo-app-service.zip" \
  -F "serviceId=demo-app" \
  -F "dirOverWrite=true" \
  "http://<device-ip>:<device-port>/v1/service/start/stream"

6.4 直接调用设备侧部署状态查询接口

bash
curl "http://<device-ip>:<device-port>/v1/service/progress?serviceId=demo-app"

7. ZIP 结构要求

AI App ZIP 结构:

text
demo-app/
└── pkg/
    ├── manifest.yml
    ├── icon.png
    ├── extension.zip
    └── ai-pod-service/
        └── docker-compose.yml

设备侧 service zip 结构:

text
demo-app/
├── docker-compose.yml
└── ...

AI App 规则:

  • ZIP 内必须存在且只能解析出一份 pkg/manifest.yml
  • 如果要参与服务部署,必须存在 pkg/ai-pod-service/docker-compose.yml

8. 兼容性说明

  • 自动触发部署、手动安装流式部署、平台侧 start 接口,共用同一套底层部署逻辑和同一份状态仓库。
  • 手动安装时,AI App SSE 直接透传设备侧部署进度。
  • 自动触发部署时,不返回 SSE;调用方应通过 serviceId 查询最近部署状态。