chore: prepare repository for submodule split

This commit is contained in:
2026-07-09 09:00:51 +00:00
parent 9e545cb328
commit e9a2400c48
33 changed files with 4175 additions and 1545 deletions
+84 -53
View File
@@ -48,6 +48,8 @@ MainApp.exe 当前仓库内的示例业务程序
- 读取 `config/app_config.json` 配置。
- 首次设备登记和本地设备身份校验。
- License 校验。
- `license_key` 为空时,`Launcher.exe` 会弹窗让用户粘贴后台创建的 License,并写入 `config/app_config.json`。当前实现会先检查配置项;即使本地已有 `config/client_identity.dat`,只要清空 `license_key` 仍会提示用户补填 License。
- License 过期、错误、禁用、设备数达到上限或设备身份凭证与授权不匹配时,`Launcher.exe` 会引导用户重新输入 License,而不是要求用户手动查找配置文件。
- 版本策略校验。
- 防止策略序号回退。
- 检测系统时间回拨。
@@ -58,7 +60,7 @@ MainApp.exe 当前仓库内的示例业务程序
- 升级后健康检查 `--health-file`,业务程序启动成功后写入 `ok`
- 升级失败回滚。
- 升级日志和下载日志上报服务端。
- `admin.html` 管理后台布局已优化。
- `server/admin.html` 管理后台布局已优化,升级日志和下载日志默认折叠
## 三、客户端 SDK 交付状态
@@ -104,7 +106,7 @@ server/main.py
server/db.py
server/tables.sql
server/minio_tool.py
server/admin.html 已不再保留,当前使用 client/admin.html
server/admin.html 服务端管理后台页面,Docker 构建时复制进镜像
```
已经实现的能力:
@@ -114,6 +116,8 @@ server/admin.html 已不再保留,当前使用 client/admin.html
- License 管理。
- 设备首次登记。
- 版本发布。
- 版本发布支持两种方式:选择软件发布根目录,或上传压缩好的发布包。管理页面已经拆成“软件根目录/压缩发布包”两个发布方式,避免用户误以为只能选择文件夹。
- 压缩发布包支持 `zip``tar.gz``tgz``tar.bz2``tbz2``rar`;服务端会先解压,再按 `RELEASE_MAIN_EXECUTABLE` 校验主程序路径。
- Manifest 生成和私钥签名。
- MinIO 对象存储上传版本文件。
- 客户端检查更新接口。
@@ -161,10 +165,8 @@ server/Dockerfile
server/docker-compose.yml
server/docker-compose.image.yml
server/package-offline-server.sh
server/package-offline-server.ps1
server/.env.example
server/.env.docker.example
server/服务端Docker镜像交付说明.md
```
Ubuntu 主流程使用:
@@ -195,6 +197,8 @@ server/dist/SimCAEServerDockerPackage.tar.gz
- `keys/manifest_private_key.pem`
- `keys/manifest_public_key.pem`
当前 Docker 镜像内已安装 `libarchive-tools`,用于后台发布 `.rar` 压缩包时调用 `bsdtar` 解压。`zip``tar.*` 由 Python 标准库直接支持。
注意:Docker 镜像包只包含软件本体和部署配置,不包含已经运行出来的数据。当前服务器上的数据库、上传过的版本文件、崩溃报告等数据在:
```text
@@ -246,9 +250,11 @@ manifest_public_key.pem
- Dockerfile 和 docker-compose 文件。
- `.env.example``.env.docker.example`
- Word 接入说明文档。
- 服务端 Docker 交付说明文档
- 服务端 Docker 离线包 README 生成逻辑
- `.gitignore`
默认值说明:服务端和客户端示例配置里已经放了可直接试跑的默认 token、MinIO 用户名和密码,目的是让接收方不用一上来就被配置卡住。它们可以直接用于内网联调;如果进入正式生产或公网环境,再按安全要求替换。
不建议提交:
- `client/App/`
@@ -262,14 +268,41 @@ manifest_public_key.pem
- `server/keys/manifest_private_key.pem`
- 任何真实 token、License、私钥和运行日志。
## 九、后续待办
## 九、SimCAE 安装根目录模式
SimCAE 的真实目录结构是安装根目录下包含 `bin/``Licenses/``installerResources/` 和维护工具,业务主程序位于 `bin/SimCAE.exe`。当前交付配置按“SDK 在 bin、发布整个安装根目录”工作:
```text
SimCAE/
bin/
Launcher.exe
Updater.exe
Bootstrap.exe
SimCAE.exe
config/
app_config.json
manifest_public_key.pem
Licenses/
installerResources/
maintenancetool.exe
```
客户端配置使用 `install_root=..``main_executable=SimCAE.exe`,服务端配置使用 `RELEASE_MAIN_EXECUTABLE=bin/SimCAE.exe`。后台发布版本时可以选择整个 `SimCAE/` 安装根目录,也可以上传压缩好的 `SimCAE.zip` / `SimCAE.tar.gz` 等发布包;不要只选择或只压缩 `bin/`。升级事务目录固定放在 `Launcher.exe` 所在目录下,也就是 `SimCAE/bin/update/`
## 十、运行目录权限说明
当前客户端 SDK 默认把运行时状态写在 `Launcher.exe` 所在目录下,包括 `config/app_config.json``config/client_identity.dat``config/local_state.json``config/version_policy.dat``update/``update_temp/`。当 SDK 放在 `SimCAE/bin` 时,更新事务、备份、暂存文件、下载断点和 Manifest 缓存都在 `SimCAE/bin/update/`,不会再在 `SimCAE/` 根目录生成顶层 `update/`。因此联调目录必须允许当前 Windows 用户写入。
如果把软件放在 `C:\Program Files\SimCAE\bin` 并用普通用户启动,Windows 会拒绝写入,首次启动可能提示 `cannot save installation id`。当前建议先在 `D:\SimCAE_Release` 或桌面目录联调;正式要安装到 `Program Files` 时,需要补管理员提权、Windows 服务,或将运行时状态迁移到 `ProgramData` / `AppData`
## 十一、后续待办
- 等业务开发者按 SDK 文档改造 SimCAE 源码。
- 用改造后的 SimCAE Release 目录做完整升级联调。
- 确认直接启动 `SimCAE.exe` 会被拒绝,只能通过 `Launcher.exe` 启动。
- 验证升级成功、升级失败回滚、Manifest 验签失败拦截。
- 如需迁移现有服务数据,补充 `runtime/``minio_data/` 的备份恢复流程。
- 生产部署前重新生成强随机 token 和 MinIO 密码
- 交付配置已提供可直接试跑的默认 token 和 MinIO 账号密码;正式生产环境建议替换为客户自己的强随机值
- 生产私钥和测试私钥建议分开管理。
---
@@ -294,14 +327,14 @@ manifest_public_key.pem
自动升级系统的 Windows 在线更新主链路已经基本打通,并且已经从“能升级”推进到“可控、安全、可回滚、可离线导入”的阶段。客户端具备 Launcher、Updater、MainApp、Bootstrap 四个程序;服务端具备 FastAPI、SQLite、MinIO、本地回退存储、版本发布、Manifest、下载授权、升级结果上报、版本策略、设备身份、License 授权、动态渠道、离线更新包、下载日志、管理员审计日志和管理网页。客户端可以检查版本、验证 RSA 签名、差异下载、断点续传、备份旧文件、通过 Bootstrap 替换被占用文件、删除废弃文件、启动新版本并等待健康确认;失败时可以进入自动回滚流程。
SimCAE 崩溃报告后端已经完成第一阶段核心接口:接收 SimCAECrashReporter.exe 上传的 metadata.json、crash.dmp 和可选 attachments.zip;根据 clientReportId 做幂等去重;校验 minidump SHA-256;保存原始文件;返回稳定 reportId;接收 CI/发布流程上传的 symbols.zip;并提供管理 token 查询和私有文件下载入口。自动符号化、聚合统计和专门后台页面属于第二阶段
SimCAE 崩溃报告后端已经完成第一阶段核心接口:接收 SimCAECrashReporter.exe 上传的 metadata.json、crash.dmp 和可选 attachments.zip;根据 clientReportId 做幂等去重;校验 minidump SHA-256;保存原始文件;返回稳定 reportId;接收 CI/发布流程上传的 symbols.zip;并提供管理 token 查询和私有文件下载入口。管理后台已经新增基础“崩溃报告”页面,可查看报告列表并下载 metadata、dmp、attachments 和 server.json。自动符号化、聚合统计、告警和问题分派属于后续增强
按两份需求文档综合判断:
1. 自动升级 Demo 主链路:约 90%~95%,剩余主要是系统性故障测试和插件真实接口加载。
2. 自动升级完整设计文档:约 75%~80%,剩余主要是正式管理员体系、限流、代码签名、灰度、多平台、插件接口版本准入和生产化测试。
3. Crash Report 第一阶段接口:约 85%90%,已经能支撑客户端联调;剩余是 HTTPS 部署、限流保留期清理和管理页面整合
4. Crash Report 完整平台:约 45%55%,因为自动符号化、统计聚合、告警和问题分派还未做。
3. Crash Report 第一阶段接口:约 90%95%,已经按需求文档完成真实 HTTP 联调;剩余是 HTTPS 部署、限流保留期清理。
4. Crash Report 完整平台:约 50%60%,因为自动符号化、统计聚合、告警和问题分派还未做。
当前最主要的剩余工作不再是普通在线更新,而是把已完成能力做实机回归、生产化安全加固,并把 SimCAE 崩溃上报客户端接入进来。
@@ -404,6 +437,8 @@ SimCAE 崩溃报告接口:
5. Manifest、MinIO 和客户端安装过程都保留相对路径。
6. 检查 MainApp.exe 是否位于发布根级。
7. 排除 Bootstrap、运行时配置、状态文件、策略缓存、PDB、ILK 和更新临时目录。
8. 支持上传压缩发布包,服务端解压后按同一套路径、主程序、文件数量和空间规则校验,并自动过滤 `update/`、`update_temp/`、构建目录、运行时配置和调试产物。
9. 压缩包可多一层顶层目录,例如 `SimCAE/bin/SimCAE.exe` 会自动归一为 `bin/SimCAE.exe`。
2.5 Manifest
@@ -450,7 +485,7 @@ SimCAE 崩溃报告接口:
1. SHA 相同的文件跳过下载。
2. HTTP Range 断点续传。
3. 使用 update/download_cache/<sha256>.part 保存片段。
3. 使用运行目录下的 `update/download_cache/<sha256>.part` 保存片段SimCAE 场景中即 `SimCAE/bin/update/download_cache/`
4. Updater 重启后仍可继续未完成文件。
5. 单文件最多自动重试四次。
6. 使用递增等待时间重试。
@@ -473,7 +508,7 @@ SimCAE 崩溃报告接口:
2.9 升级事务状态机
已实现 update/upgrade_state.json,包含:
已实现运行目录下的 `update/upgrade_state.json`SimCAE 场景中即 `SimCAE/bin/update/upgrade_state.json`,包含:
1. transaction_id。
2. from_version。
@@ -557,6 +592,8 @@ Updater 启动时会读取旧事务,并根据状态尝试恢复或回滚。
10. 降级目标协议低于当前客户端协议时,服务端在安装前返回 rollback_denied。
11. 管理后台支持查看和修正历史版本的协议标签。
这里的“客户端协议”不是 HTTP 协议,也不是软件版本号,而是 Launcher/Updater 支持的升级机制能力编号。当前默认是 `3`,代表支持一次性启动票据、健康检查、策略校验、受控降级等当前客户端机制;普通发布保持默认值即可,只有未来客户端升级机制发生不兼容变化时才需要调整。
2.14 离线运行基础
已实现:
@@ -581,15 +618,16 @@ Updater 启动时会读取旧事务,并根据状态尝试恢复或回滚。
2. 修改管理员令牌。
3. 创建和选择应用。
4. 选择软件根目录发布。
5. stable、preview、dev 渠道选择
6. 版本列表
7. 设置最新版本。
8. 删除版本和云端文件
9. 版本策略读取和保存
10. 升级日志
11. 调试输出
12. 发布文件预览、大小和状态提示
13. 页面美化和响应式布局
5. 切换到“压缩发布包”模式上传压缩包发布,支持 zip、tar.gz、tgz、tar.bz2、tbz2、rar
6. stable、preview、dev 渠道选择
7. 版本列表
8. 设置最新版本
9. 删除版本和云端文件
10. 版本策略读取和保存
11. 升级日志
12. 调试输出
13. 发布文件预览、大小和状态提示
14. 页面美化和响应式布局。
2.16 一次性短期启动票据
@@ -627,12 +665,14 @@ Updater 启动时会读取旧事务,并根据状态尝试恢复或回滚。
3. 服务端逐请求验证设备凭证、授权状态、设备禁用状态、app_id 和 channel。
4. License 授权:licenses 和 license_devices 表,支持有效期、启用/禁用、最大设备数和设备占用。
5. 授权密钥只保存 SHA-256,明文只在创建时返回一次。
6. 动态渠道:channels 表按 app_id 隔离,管理后台支持新增、编辑、启用和停用
7. 发布、策略、授权、设备登记和更新检查统一校验渠道
8. 离线更新包:管理后台可生成 MUPD0001/.upd 包,包内包含签名 Manifest、包头签名、文件偏移、大小和 SHA-256
9. Launcher/Updater 支持导入离线包,离线安装复用现有事务、Bootstrap、校验、健康确认和回滚机制
10. 下载日志:记录下载授权、客户端完成结果、文件大小、IP、User-Agent 和时间
11. 管理员审计日志:记录 /admin 写操作、管理员令牌指纹、路径、结果、状态码、IP 和 User-Agent
6. Launcher 首次启动时如果没有 License,会弹窗要求用户输入并自动写入配置;当前实现会先检查 `license_key` 配置项,即使本地已有 `client_identity.dat`,清空 `license_key` 仍会触发输入框
7. License 错误、过期、禁用、设备数达到上限或设备身份与授权不匹配时,Launcher 会清理旧设备身份并引导用户重新输入 License
8. 动态渠道:channels 表按 app_id 隔离,管理后台支持新增、编辑、启用和停用
9. 发布、策略、授权、设备登记和更新检查统一校验渠道
10. 离线更新包:管理后台可生成 MUPD0001/.upd 包,包内包含签名 Manifest、包头签名、文件偏移、大小和 SHA-256
11. Launcher/Updater 支持导入离线包,离线安装复用现有事务、Bootstrap、校验、健康确认和回滚机制
12. 下载日志:记录下载授权、客户端完成结果、文件大小、IP、User-Agent 和时间。
13. 管理员审计日志:记录 /admin 写操作、管理员令牌指纹、路径、结果、状态码、IP 和 User-Agent。
2.19 SimCAE Crash Report 后端第一阶段
@@ -654,8 +694,11 @@ Updater 启动时会读取旧事务,并根据状态尝试恢复或回滚。
14. POST /api/v1/symbols 接收 CI/发布流程上传的 metadata.json 和 symbols.zip。
15. crash_symbol_uploads 表按 product、appVersion、gitCommit、buildType、platform 索引符号包。
16. 已配置 CRASH_STORAGE_ROOTDocker 部署时落到 /data/crash_storage 持久化目录。
17. 管理后台新增“崩溃报告”页面,登录后可查看 report_id、版本、gitCommit、构建类型、渠道、异常码、崩溃时间、接收时间、来源 IP 和文件大小。
18. 管理后台可下载单条崩溃报告的 metadata.json、crash.dmp、attachments.zip 和 server.json,并写入 crash_file_access_logs。
19. 已按需求文档的 curl 联调思路完成真实 HTTP 测试:上传成功、重复上传幂等、内容冲突 409、错误 token 401、缺 metadata 400、minidump SHA-256 错误 400、管理查询、原始文件下载、符号包上传和符号包重复上传均通过。
说明:第一阶段只做“可靠接收、校验、保存、索引查询”。自动符号化、聚合统计、告警问题分派和专门后台页面属于第二阶段
说明:第一阶段已经做到“可靠接收、校验、保存、索引查询和后台查看/下载”。自动符号化、聚合统计、告警问题分派属于后续增强
============================================================
三、部分实现的功能
@@ -757,7 +800,7 @@ RSA 签名已经实现,但仍缺少:
1. 自动符号化,把 crash.dmp 转成可读调用栈。
2. 根据 appVersion、gitCommit、buildType 自动匹配 symbols.zip。
3. 崩溃报告列表、搜索、下载和统计后台页面。
3. 崩溃报告高级搜索、筛选、统计和详情页面。
4. 按异常码、版本、GPU、命令、项目等维度聚合。
5. 保留期清理,例如 90 天或 180 天。
6. 上传限流和异常峰值告警。
@@ -1213,7 +1256,7 @@ SDK 是 Software Development Kit,中文通常叫“软件开发工具包”。
它不是单个 exe,也不只是源码,而是一套让别人能把你的能力接到自己软件里的交付包。一个合格 SDK 通常包含:
1. 可直接使用的二进制文件,例如 Launcher.exe、Updater.exe、Bootstrap.exe。
2. 必要的运行时 DLL,例如 Qt、OpenSSL、平台插件等
2. 必要的运行时文件。对 SimCAE 这种自身已带 Qt 的软件,SDK 默认不再携带 Qt DLL,避免覆盖业务软件原有运行库
3. 配置模板,例如 app_config.example.json。
4. 接入文档,例如如何配置 app_id、channel、api_base_url、license_key。
5. 打包脚本,例如 package-client.ps1。
@@ -1254,38 +1297,26 @@ SDK 是 Software Development Kit,中文通常叫“软件开发工具包”。
建议最终交付类似下面的目录:
UpdateClientSDK/
README.md
docs/
接入说明.md
服务端接口说明.md
常见错误.md
SimCAE自动升级SDK接入说明_v0.1.docx
sdk_manifest.json
bin/
Launcher.exe
Updater.exe
Bootstrap.exe
Qt5Core.dll
Qt5Gui.dll
Qt5Widgets.dll
Qt5Network.dll
platforms/qwindows.dll
openssl 相关 DLL
config/
app_config.example.json
app_config.json
manifest_public_key.pem
scripts/
install-sdk.ps1
package-client.ps1
samples/
minimal_app/
MainApp.exe 或示例源码
app_config.json 示例
package-sdk.ps1
对接方真正拿到后,通常只需要做这些事:
1. 把自己的主程序和依赖 DLL 放到发布目录。
2. 设置 app_config.jsonserver 地址、app_id、channel、当前版本、license_key、主程序名等
1. 把 SDK 的 Launcher、Updater、Bootstrap 放到业务软件运行目录。
2. 设置 app_config.jsonserver 地址、app_id、channel、当前版本、主程序名等。`license_key` 可以预先填入;如果为空,用户首次启动 Launcher 时会弹窗粘贴授权密钥
3. 以后让用户启动 Launcher.exe。
4. 在管理后台创建应用、License、渠道和发布版本。
5. 发布新版本时选择干净的 Release 输出目录。
5. 发布新版本时选择干净的 Release 输出目录,或切换到“压缩发布包”模式上传 zip/tar.gz/tar.bz2/rar 等压缩发布包
10.4 当前已有 package-client.ps1 的作用
@@ -1357,7 +1388,7 @@ Docker 运行时,依赖的是镜像里的 Python、镜像里的依赖、容器
1. 使用 python:3.12-slim 作为基础镜像。
2. 安装 server/requirements.txt 里的 FastAPI、MinIO、cryptography 等依赖。
3. 拷贝 main.py、db.py、minio_tool.py、tables.sql。
4. 拷贝 client/admin.html 到容器内 /app/admin.html。
4. 拷贝 server/admin.html 到容器内 /app/admin.html。
5. 使用非 root 用户 updateapp 运行。
6. 暴露 8000 端口。
7. 提供 healthcheck。
@@ -1469,7 +1500,7 @@ Docker 是给“服务端部署人员”用的。
第二步:准备客户端 SDK 包。
1. 确认 client/out/bin 是 Release 输出目录。
2. 确认 out/bin 里有 Launcher.exe、Updater.exe、Bootstrap.exe、Qt DLL、platforms/qwindows.dll
2. 确认 out/bin 里有 Launcher.exe、Updater.exe、Bootstrap.exe。SimCAE 场景下不要把 SDK 自带 Qt DLL 覆盖到 SimCAE 的 bin 目录
3. 确认 config/manifest_public_key.pem 是服务端私钥对应的公钥。
4. 填好 client/config/app_config.example.json 里的示例字段。
5. 在 Windows PowerShell 执行:
@@ -1495,7 +1526,7 @@ cd client
第五步:补接入方文档和 Demo。
1. 把 client/SDK_README.md 随 SDK 一起交付
1. SDK 根目录只保留一个 Word 接入说明作为入口,打开包后一眼能看到
2. 准备一个最小 MainApp 示例,演示 --ticket-file 和 --health-file。
3. 准备一份常见错误说明。
4. 准备一份服务端 Docker 部署说明。