3588AdminBackend/Readme.md

329 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# managerd
`managerd` 是 RK3588 管理端后端服务,负责设备发现、设备注册表维护、代理访问设备端 `rk3588-agent`,并提供内嵌 Web UI、OpenAPI 页面和 HTTP API。
## 当前状态
- 提供 HTTP API供前端或其他本地工具调用。
- 内嵌 Web UI启动后可直接在浏览器访问。
- 支持 UDP 广播发现设备,并维护内存中的设备在线状态。
- 支持代理访问设备端 agent 的常用接口,以及 `/v1/*` 通用透传。
- 支持批量任务执行,并通过 SSE 推送逐设备状态。
- 模板从本地 `templates/*.json` 读取。
## 运行方式
默认通过单个可执行文件运行:
```bash
managerd
```
也可以指定配置文件路径:
```bash
managerd path/to/managerd.json
```
在当前仓库的 Windows 开发环境中,推荐使用统一脚本入口:
```bat
scripts\managerd.bat build
scripts\managerd.bat start
scripts\managerd.bat stop
scripts\managerd.bat restart
scripts\managerd.bat status
```
各动作说明:
- `build`: 编译 `.\cmd\managerd`,生成根目录下的 `managerd.exe`
- `start`: 启动当前仓库中的 `managerd.exe`,并检查 `/health`
- `stop`: 停止当前仓库对应的 `managerd.exe`
- `restart`: 先停止再启动
- `status`: 查看进程状态与健康检查结果
脚本实际入口文件:
- `scripts/managerd.bat`
- `scripts/managerd.ps1`
程序启动后:
- `GET /` 会重定向到 `/ui`
- `GET /ui` 为内嵌管理页面
- `GET /openapi.json` 返回 OpenAPI 描述
- `GET /health` 返回健康检查结果
当前仓库中的示例配置监听地址为 `0.0.0.0:18080`
## 依赖
- Go `1.23.3`
- `github.com/go-chi/chi/v5`
- `github.com/go-chi/cors`
- `github.com/google/uuid`
## 主要模块
### Discovery
- 向所有可用广播网卡发送 UDP discover 请求
- 在本地临时 UDP 端口监听回复
-`device_id` 去重,并使用最新回复更新注册表
### Device Registry
- 以内存维护设备列表
- 每 2 秒执行一次离线判定
- 超过 `offline_after_ms` 未更新则标记为离线
- 每 30 秒对在线设备拉取一次 `GET /v1/graphs`,更新 `graphs` 字段
- 除 UDP 发现外,成功代理调用设备接口时也会刷新设备 `last_seen_ms`
### Agent Client
- 默认 HTTP 请求超时为 3 秒
- 对配置下发、模型上传、`/v1/config/ui/*`、人脸库上传等长操作使用 120 秒超时
- 自动附带全局 `X-RK-Token`
### Template Service
- 从本地 `templates/` 目录加载 `.json` 模板
- 返回模板列表和单个模板详情
- 当前没有实现 embed 模板加载
### Task Runner
- 支持并发执行,默认并发数为 `concurrency`
- 支持 SSE 推送逐设备状态
- 当前支持的任务类型:
- `config_apply`
- `reload`
- `rollback`
- `media_start`
- `media_restart`
- `media_stop`
## API 概览
### 基础接口
- `GET /health`
- `GET /openapi.json`
- `GET /` -> 302 跳转到 `/ui`
- `GET /ui`
### Discovery
#### `POST /api/discovery/search`
Request:
```json
{ "timeout_ms": 1200 }
```
Response:
```json
{
"items": [
{
"device_id": "...",
"hostname": "...",
"ip": "...",
"agent_port": 9100,
"media_port": 9000,
"device_name": "...",
"version": "...",
"git_sha": "...",
"uptime_sec": 0,
"last_seen_ms": 0,
"online": true
}
]
}
```
### Devices
#### `GET /api/devices`
返回当前注册表中的设备列表:
```json
{
"items": [
{
"device_id": "...",
"hostname": "...",
"ip": "...",
"agent_port": 9100,
"media_port": 9000,
"device_name": "...",
"version": "...",
"git_sha": "...",
"uptime_sec": 0,
"last_seen_ms": 0,
"online": true,
"graphs": {}
}
]
}
```
#### `POST /api/devices`
手工添加一个设备到注册表:
```json
{
"device_id": "demo-device",
"device_name": "Demo",
"ip": "192.168.1.10",
"agent_port": 9100,
"media_port": 9000
}
```
#### `GET /api/devices/{id}`
直接返回该设备对象。
### 设备代理接口
以下接口由 managerd 转发到设备端 agent
- `GET /api/devices/{id}/info` -> `GET /v1/info`
- `POST /api/devices/{id}/reload` -> `POST /v1/media-server/reload`
- `POST /api/devices/{id}/rollback` -> `POST /v1/media-server/rollback`
- `GET /api/devices/{id}/graphs` -> `GET /v1/graphs`
- `GET /api/devices/{id}/graphs/{name}` -> `GET /v1/graphs/{name}`
- `GET /api/devices/{id}/logs?limit=200` -> `GET /v1/logs/recent?limit=200`
- `POST /api/devices/{id}/config/apply` -> `PUT /v1/config`
- `GET /api/devices/{id}/models` -> `GET /v1/models`
- `POST /api/devices/{id}/media-server/start` -> `POST /v1/media-server/start`
- `POST /api/devices/{id}/media-server/restart` -> `POST /v1/media-server/restart`
- `POST /api/devices/{id}/media-server/stop` -> `POST /v1/media-server/stop`
- `GET /api/devices/{id}/media-server/status` -> `GET /v1/media-server/status`
#### 通用透传
- `ANY /api/devices/{id}/v1/*`
该路由会将 `/api/devices/{id}` 之后的路径原样透传到设备端 agent可用于
- `/v1/config`
- `/v1/config/ui/schema`
- `/v1/config/ui/state`
- `/v1/config/ui/plan`
- `/v1/config/ui/apply`
- `/v1/face-gallery`
- `/v1/face-gallery/reload`
- 以及其他已存在的 `/v1/*` 接口
### 模型上传
#### `POST /api/devices/{id}/models/upload`
请求类型:`multipart/form-data`
字段:
- `name`: 模型名
- `file`: 二进制文件
行为managerd 读取上传文件,并转发为设备端 agent 的 `PUT /v1/models/{name}`
### Templates
- `GET /api/templates`
- `GET /api/templates/{name}`
当前模板数据来自本地 `templates/*.json`
### Tasks
#### `POST /api/tasks`
Request:
```json
{
"type": "config_apply",
"device_ids": ["device-a", "device-b"],
"payload": {
"config": {}
}
}
```
说明:
- `config_apply` 会将 payload 作为配置内容下发到 `/v1/config`
- `media_start``media_restart` 可选接收 `{"config":"xxx"}` 形式的 payload
Response:
```json
{ "task_id": "..." }
```
#### `GET /api/tasks`
返回当前内存中的任务列表。
#### `GET /api/tasks/{id}/events`
SSE 事件名为 `device_update`,数据格式:
```json
{
"device_id": "...",
"status": "running",
"progress": 0.0,
"error": ""
}
```
## 配置文件
`managerd.json` 示例:
```json
{
"listen": "0.0.0.0:18080",
"discovery_port": 35688,
"discovery_timeout_ms": 1200,
"offline_after_ms": 10000,
"agent_token": "CHANGE_ME",
"concurrency": 5
}
```
字段说明:
- `listen`: managerd 监听地址
- `discovery_port`: 设备发现广播端口
- `discovery_timeout_ms`: 搜索超时
- `offline_after_ms`: 多久未更新则视为离线
- `agent_token`: 转发到设备端 agent 的统一 token
- `concurrency`: 批量任务并发数
## 目录说明
- `cmd/managerd`: 程序入口
- `internal/api`: API 路由与处理器
- `internal/service`: discovery、registry、task、template、agent client
- `internal/web`: 内嵌 Web UI
- `templates`: 本地模板
- `scripts/deploy`: 部署脚本
## 验证现状
当前仓库已通过:
```bash
go test ./...
```