Files
hawkbit/hawkbit-compose/README.md
lingwei.kong 2a425196e6
Some checks failed
Mark & close stale issues / stale (push) Has been cancelled
Vulnerability Scan / trivy-scan (1.0) (push) Has been cancelled
Vulnerability Scan / trivy-scan (master) (push) Has been cancelled
License Scan / license-scan (push) Has been cancelled
提交api调用相关信息
2026-06-18 18:00:17 +08:00

215 lines
8.3 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.
# Hawkbit DDI Client
轻量级纯 Python OTA 更新代理,零依赖(仅 Python 3 标准库),可在 **Android adb shell** 和 **Linux 主机**上运行。
## 功能
| 功能 | 说明 |
|------|------|
| **轮询** | `GET /{tenant}/controller/v1/{controllerId}` 查询部署任务,自动适配服务端建议的轮询间隔 |
| **断点下载** | HTTP `Range` 请求实现断点续传,临时 `.tmp` 文件保留至下载完成 |
| **SHA256 校验** | 下载完成后自动与部署元数据中的哈希值比对 |
| **状态上报** | 完整状态链:`download``downloaded``proceeding``closed(success/failure)` |
| **设备 SN 检测** | 自动检测序列号Android `ro.serialno` → DMI `product_serial``/etc/machine-id` → hostname |
| **设备属性上报** | 首次连接自动上报设备属性osType, platform, hwRevision, kernel…供 Hawkbit target filter 匹配 |
| **认证** | 支持 `GatewayToken``TargetToken`,也支持从文件读取:`--gateway-token @/etc/hawkbit/gateway.key` |
| **取消/确认** | 处理 `cancelAction`(取消任务)和 `confirmationBase`headless 自动确认) |
### 设备属性上报
脚本在**首次轮询**时自动调用 `PUT …/configData` 上报以下属性:
| 属性 | 来源 | 示例 |
|------|------|------|
| `osType` | `/system/build.prop` 或 uname | `android` / `linux` |
| `platform` | `platform.machine()` | `aarch64` / `x86_64` |
| `kernel` | `os.uname().release` | `6.17.0-35-generic` |
| `hwRevision` | DMI product_name + product_version | `VMware Virtual Platform` |
| `manufacturer` | DMI sys_vendor 或 Android ro.product.manufacturer | `VMware, Inc.` |
| `hostname` | `socket.gethostname()` | `device-001` |
| `swVersion` | `/etc/hawkbit/current_version`(可选) | `V1.0.0.0` |
**扩展属性**:创建 `/etc/hawkbit/device_attrs.json` 添加自定义属性:
```json
{"dept": "production", "region": "east", "owner": "team-a"}
```
这些属性在 Hawkbit 里就是 target 的 attributes管理员创建 target filter 时可以直接用:
```
属性 osType=android AND hwRevision=VMware → 自动分配 V2.0 更新
## 快速开始
```bash
# 网关令牌,每 30 秒轮询
python3 ddi-client.py -u https://hawkbit.example.com -t DEFAULT --gateway-token s3cret -i 30
# 网关令牌从文件读取(生产推荐)
echo "s3cret" > /etc/hawkbit/gateway.key
chmod 600 /etc/hawkbit/gateway.key
python3 ddi-client.py -u https://hawkbit.example.com -t DEFAULT \
--gateway-token @/etc/hawkbit/gateway.key -i 30
# 目标令牌,单次轮询
python3 ddi-client.py -u http://10.0.0.1:8080 -t DEFAULT --target-token tok --once
# 自定义设备 ID + 自定义属性文件,调试模式
python3 ddi-client.py -u https://hawkbit:8443 -t prod \
--gateway-token @/etc/hawkbit/gateway.key \
--controller-id edge-042 -d /data/ota -v
```
## 命令行参数
```
-u, --base-url Hawkbit 服务端地址(必填)
-t, --tenant 租户名称,如 DEFAULT必填
--gateway-token Gateway 安全令牌
--target-token Target 安全令牌
--controller-id 控制器 ID默认自动检测设备序列号
-d, --download-dir 下载目录,默认 /tmp/hawkbit
-i, --polling-interval 轮询间隔(秒),默认 60可被服务端覆盖
--no-verify 跳过 SHA256 校验
--no-resume 禁用断点续传
--no-ssl-verify 禁用 TLS 证书验证(不安全)
--once 仅轮询一次后退出
-v, --verbose 调试级日志
-h, --help 帮助信息
```
## DDI API 流程
```
┌─────────┐ ① GET /{tenant}/controller/v1/{controllerId} ┌──────────┐
│ │ ────────────────────────────────────────────────────→ │ │
│ 设备 │ ←──── HAL links (deploymentBase / cancel / …) │ Hawkbit │
│ │ │ Server │
│ │ ② GET …/deploymentBase/{actionId} │ │
│ │ ────────────────────────────────────────────────────→ │ │
│ │ ←──── chunks[].artifacts[] (filename, SHA256, │ │
│ │ download URL) │ │
│ │ │ │
│ │ ③ GET …/softwaremodules/{id}/artifacts/{file} │ │
│ │ ────────────────────────────────────────────────────→ │ │
│ │ ←──── 二进制流(支持 Range 断点续传) │ │
│ │ │ │
│ │ ④ POST …/deploymentBase/{actionId}/feedback │ │
│ │ ───── {execution, result, details} ────────────────→ │ │
│ │ ←──── 200 OK │ │
└─────────┘ └──────────┘
```
### 状态上报 JSON 格式
```json
{
"timestamp": 1750000000000,
"status": {
"execution": "download",
"result": {
"finished": "none"
},
"details": ["Starting download"]
}
}
```
| execution 值 | 含义 | result.finished |
|-------------|------|-----------------|
| `download` | 开始下载 | `none` |
| `downloaded` | 下载完成 | `none` |
| `proceeding` | 安装中 | `none` |
| `closed` | 最终状态 | `success` / `failure` |
| `canceled` | 已取消 | `none` |
| `rejected` | 已拒绝 | `none` |
## 认证配置
### Target Token推荐每设备独立令牌
在 Hawkbit Management API 中为目标设置 security token
```bash
curl -u admin:admin -X PUT \
-H "Content-Type: application/json" \
"http://<hawkbit>:9090/rest/v1/targets/<controllerId>" \
-d '{"securityToken": "my-device-token"}'
```
启用租户级 TargetToken 认证:
```bash
curl -u admin:admin -X PUT \
-H "Content-Type: application/json" \
"http://<hawkbit>:9090/rest/v1/system/configs/authentication.targettoken.enabled" \
-d '{"value": true}'
```
### Gateway Token所有设备共享同一令牌
```bash
# 设置 token key
curl -u admin:admin -X PUT \
-H "Content-Type: application/json" \
"http://<hawkbit>:9090/rest/v1/system/configs/authentication.gatewaytoken.key" \
-d '{"value": "my-gateway-key"}'
# 启用
curl -u admin:admin -X PUT \
-H "Content-Type: application/json" \
"http://<hawkbit>:9090/rest/v1/system/configs/authentication.gatewaytoken.enabled" \
-d '{"value": true}'
```
## 设备 SN 检测优先级
| 优先级 | 来源 | 适用平台 |
|--------|------|---------|
| 1 | `getprop ro.serialno` | Android |
| 2 | `/sys/class/dmi/id/product_serial` | Linux (x86) |
| 3 | `/sys/devices/virtual/dmi/id/product_serial` | Linux (ARM / 嵌入式) |
| 4 | `/etc/machine-id` | systemd Linux |
| 5 | `socket.gethostname()` | 通用回退 |
## 安装钩子
下载完成后,脚本调用 `_install(files, handling)` 方法执行实际安装。**默认实现仅做文件存在性检查,生产环境必须覆盖此方法**。
### 方式一:子类继承
```python
from ddi_client import HawkbitDDIClient
class MyClient(HawkbitDDIClient):
def _install(self, files, handling):
import subprocess
for f in files:
subprocess.run(["unzip", "-o", f, "-d", "/data/ota"], check=True)
return True
```
### 方式二Monkey-Patch
```python
client = HawkbitDDIClient(...)
client._install = lambda files, h: do_my_install(files)
```
## 兼容性
- Python ≥ 3.7
- Android (adb shell, 需安装 Python)
- Linux (x86_64 / aarch64 / armv7l)
- macOS
- Hawkbit DDI API v1
## 文件结构
```
ddi-client.py # 脚本本体(单文件,可直接部署)
```
无其他依赖文件。