From 3be5101932ecedcea2dc72fcf29ba98636886370 Mon Sep 17 00:00:00 2001 From: nikelaluo <2135665716@qq.com> Date: Tue, 14 Jul 2026 01:39:30 +0000 Subject: [PATCH] chore: update submodule references --- .gitignore | 126 +++++++++++++++++++++++++-------------- update-client | 2 +- update-server | 2 +- 项目总览.md | 162 ++++++++++++++++++++++++++++++-------------------- 4 files changed, 182 insertions(+), 110 deletions(-) diff --git a/.gitignore b/.gitignore index 8cac7ed..4f834ff 100644 --- a/.gitignore +++ b/.gitignore @@ -27,12 +27,20 @@ Desktop.ini *.rar # Requirement / handover documents kept outside Git -client/*.pdf -client/*.doc -client/*.docx -server/*.doc -server/*.docx -server/*交付说明*.md +update-client/*.pdf +update-client/*.doc +update-client/*.docx +update-client/Docs/*.pdf +update-client/Docs/*.doc +update-client/Docs/*.docx +update-client/private/ +update-client/pdf_requirements.txt +update-server/*.pdf +update-server/*.doc +update-server/*.docx +update-server/Docs/*.pdf +update-server/Docs/*.doc +update-server/Docs/*.docx # C/C++ generated artifacts outside build directories *.obj @@ -48,53 +56,88 @@ server/*交付说明*.md *.exe # Client: CMake / Visual Studio build outputs -client/out/ -client/build/ -client/build-*/ -client/cmake-build-*/ -client/.cmake/ -client/CMakeFiles/ -client/CMakeCache.txt -client/CMakeSettings.json -client/CMakeUserPresets.json -client/Testing/ +update-client/out/ +update-client/build/ +update-client/build-*/ +update-client/cmake-build-*/ +update-client/.cmake/ +update-client/CMakeFiles/ +update-client/CMakeCache.txt +update-client/CMakeSettings.json +update-client/CMakeUserPresets.json +update-client/Testing/ # Client: third-party/business binary drops and generated packages -client/App/ -client/dist/ +update-client/thirdparty/ +update-client/App/ +update-client/dist/ # Client: local runtime state and credentials +update-client/config/app_config.json +update-client/config/client_identity.dat +update-client/config/local_state.json +update-client/config/version_policy.dat +update-client/config/*.local.json +update-client/config/*private*.pem +update-client/config/*private*.key +update-client/update/ +update-client/update_temp/ + +# Server: Python environments and caches +update-server/venv/ +update-server/.venv/ +update-server/__pycache__/ +update-server/**/*.py[cod] +update-server/.pytest_cache/ +update-server/.mypy_cache/ +update-server/.ruff_cache/ +update-server/.coverage +update-server/htmlcov/ + +# Server: local configuration and secrets +update-server/.env +update-server/.env.* +!update-server/.env.example +!update-server/.env.docker.example +update-server/admin_token.sha256 +update-server/keys/*private*.pem +update-server/keys/*private*.key + +# Server: runtime databases, uploads, object storage and generated packages +update-server/*.db +update-server/*.db-journal +update-server/*.db-wal +update-server/*.db-shm +update-server/local_uploads/ +update-server/upload_spool/ +update-server/crash_storage/ +update-server/minio_data/ +update-server/runtime/ +update-server/dist/ +update-server/minio + +# Server: runtime files +update-server/*.pid +update-server/*.log + +# Docker/local generated files +.dockerignore.local + +# Legacy paths before splitting into update-client/update-server submodules +client/out/ +client/build/ +client/App/ +client/dist/ client/config/app_config.json client/config/client_identity.dat client/config/local_state.json client/config/version_policy.dat -client/config/*.local.json -client/config/*private*.pem -client/config/*private*.key -client/update/ -client/update_temp/ - -# Server: Python environments and caches server/venv/ server/.venv/ server/__pycache__/ server/**/*.py[cod] -server/.pytest_cache/ -server/.mypy_cache/ -server/.ruff_cache/ -server/.coverage -server/htmlcov/ - -# Server: local configuration and secrets server/.env server/.env.* -!server/.env.example -!server/.env.docker.example -server/admin_token.sha256 -server/keys/*private*.pem -server/keys/*private*.key - -# Server: runtime databases, uploads, object storage and generated packages server/*.db server/*.db-journal server/*.db-wal @@ -106,10 +149,5 @@ server/minio_data/ server/runtime/ server/dist/ server/minio - -# Server: runtime files server/*.pid server/*.log - -# Docker/local generated files -.dockerignore.local diff --git a/update-client b/update-client index cb5819a..94b20bf 160000 --- a/update-client +++ b/update-client @@ -1 +1 @@ -Subproject commit cb5819ab7c22e9267808834c807e349919a0779d +Subproject commit 94b20bf2bb1fbb446c6ad7829699e50df2d1fe71 diff --git a/update-server b/update-server index 9a6ac1e..95dd32c 160000 --- a/update-server +++ b/update-server @@ -1 +1 @@ -Subproject commit 9a6ac1e4edc3f0b84e1ef9ef5004a537bbca19d9 +Subproject commit 95dd32c75ac47d6a3284024ff3258d824ecc964e diff --git a/项目总览.md b/项目总览.md index 9ddae33..f2b6c1d 100644 --- a/项目总览.md +++ b/项目总览.md @@ -9,8 +9,16 @@ 整体分为两部分: ```text -client/ Windows 客户端升级运行时、SDK 打包脚本、接入说明文档 -server/ FastAPI 服务端、后台页面、Docker 部署和离线交付脚本 +update-client/ Windows 客户端升级运行时、SDK 打包脚本、接入说明文档 +update-server/ FastAPI 服务端、后台页面、Docker 部署和离线交付脚本 +``` + +文档放置约定: + +```text +项目总览.md 项目整体说明,保留在总仓库根目录 +update-client/Docs/ 客户端说明文档 +update-server/Docs/ 服务端说明文档 ``` 客户端负责: @@ -45,10 +53,10 @@ MainApp.exe 当前仓库内的示例业务程序 已经实现的能力: -- 读取 `config/app_config.json` 配置。 +- 首次启动时把 `config/app_config.json` 导入当前 Windows 用户注册表,后续运行配置优先从注册表读取;如果解析后的 JSON 内容变化,下一次启动会自动重新导入,并清理 `config/client_identity.dat` 和 `config/version_policy.dat`。 - 首次设备登记和本地设备身份校验。 - License 校验。 -- `license_key` 为空时,`Launcher.exe` 会弹窗让用户粘贴后台创建的 License,并写入 `config/app_config.json`。当前实现会先检查配置项;即使本地已有 `config/client_identity.dat`,只要清空 `license_key` 仍会提示用户补填 License。 +- `license_key` 为空时,`Launcher.exe` 会弹窗让用户粘贴后台创建的 License,并写入注册表。当前实现会先检查配置项;即使本地已有 `config/client_identity.dat`,只要清空 `license_key` 仍会提示用户补填 License。 - License 过期、错误、禁用、设备数达到上限或设备身份凭证与授权不匹配时,`Launcher.exe` 会引导用户重新输入 License,而不是要求用户手动查找配置文件。 - 版本策略校验。 - 防止策略序号回退。 @@ -60,15 +68,23 @@ MainApp.exe 当前仓库内的示例业务程序 - 升级后健康检查 `--health-file`,业务程序启动成功后写入 `ok`。 - 升级失败回滚。 - 升级日志和下载日志上报服务端。 -- `server/admin.html` 管理后台布局已优化,升级日志和下载日志默认折叠。 +- `update-server/legacy/admin.html` 管理后台布局已优化,升级日志和下载日志默认折叠。 ## 三、客户端 SDK 交付状态 已经提供 SDK 打包脚本: ```text -client/package-sdk.ps1 -client/package-client.ps1 +update-client/scripts/package-sdk.ps1 +update-client/scripts/package-client.ps1 +``` + +客户端文档现在统一放在: + +```text +update-client/Docs/ReadMe.txt +update-client/Docs/客户端部署说明.md +update-client/Docs/第三方依赖说明.md ``` `package-sdk.ps1` 用于生成给业务开发者接入的 SDK 包。当前 SDK 包结构设计为: @@ -99,14 +115,27 @@ Word 文档已经说明: ## 四、服务端当前已实现 -服务端使用 FastAPI,主要文件: +服务端使用 FastAPI。当前后端已经从早期单文件形态拆成分层结构,主要入口和目录: ```text -server/main.py -server/db.py -server/tables.sql -server/minio_tool.py -server/admin.html 服务端管理后台页面,Docker 构建时复制进镜像 +update-server/main.py 应用启动、数据库初始化、MinIO 初始化、全局客户端鉴权 +update-server/app/api/routes/ 管理端、客户端更新、崩溃报告等 HTTP 路由 +update-server/app/services/ 发布、签名、License、设备凭证、崩溃报告等业务逻辑 +update-server/app/repositories/ SQLite 数据库读写层 +update-server/app/schemas/ Pydantic 请求模型 +update-server/db.py +update-server/tables.sql +update-server/minio_tool.py +update-server/admin-ui/ 新版管理后台源码 +update-server/legacy/admin.html 旧版管理后台页面,保留兼容 +``` + +服务端文档现在统一放在: + +```text +update-server/Docs/ReadMe.txt +update-server/Docs/服务端部署说明.md +update-server/Docs/后端模板化改造说明.md ``` 已经实现的能力: @@ -125,6 +154,7 @@ server/admin.html 服务端管理后台页面,Docker 构建时复制进镜像 - 升级结果上报。 - 文件下载日志记录。 - 后台管理页面。 +- 后端已经按 `routes / services / repositories / schemas` 拆分,`main.py` 不再堆业务接口。 - Docker 运行。 - Docker 离线部署包生成。 @@ -161,20 +191,20 @@ POST /api/v1/symbols 服务端 Docker 文件: ```text -server/Dockerfile -server/docker-compose.yml -server/docker-compose.image.yml -server/package-offline-server.sh -server/.env.example -server/.env.docker.example +update-server/Dockerfile +update-server/docker-compose.yml +update-server/docker-compose.image.yml +update-server/scripts/package-offline-server.sh +update-server/.env.example +update-server/.env.docker.example ``` Ubuntu 主流程使用: ```bash -cd server +cd update-server -bash ./package-offline-server.sh \ +bash ./scripts/package-offline-server.sh \ --version 0.1.0 \ --output-dir ./dist/SimCAEServerDockerPackage ``` @@ -182,7 +212,7 @@ bash ./package-offline-server.sh \ 生成: ```text -server/dist/SimCAEServerDockerPackage.tar.gz +update-server/dist/SimCAEServerDockerPackage.tar.gz ``` 该包中包含: @@ -202,8 +232,8 @@ server/dist/SimCAEServerDockerPackage.tar.gz 注意:Docker 镜像包只包含软件本体和部署配置,不包含已经运行出来的数据。当前服务器上的数据库、上传过的版本文件、崩溃报告等数据在: ```text -server/runtime/ -server/minio_data/ +update-server/runtime/ +update-server/minio_data/ ``` 如果要完整迁移现有服务数据,需要额外备份和恢复这两个目录。 @@ -257,15 +287,15 @@ manifest_public_key.pem 不建议提交: -- `client/App/` -- `client/out/` -- `client/dist/` -- `server/dist/` -- `server/runtime/` -- `server/minio_data/` -- `server/*.db` -- `server/.env` -- `server/keys/manifest_private_key.pem` +- `update-client/App/` +- `update-client/out/` +- `update-client/dist/` +- `update-server/dist/` +- `update-server/runtime/` +- `update-server/minio_data/` +- `update-server/*.db` +- `update-server/.env` +- `update-server/keys/manifest_private_key.pem` - 任何真实 token、License、私钥和运行日志。 ## 九、SimCAE 安装根目录模式 @@ -291,9 +321,9 @@ SimCAE/ ## 十、运行目录权限说明 -当前客户端 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 用户写入。 +当前客户端 SDK 把部署配置源放在 `Launcher.exe` 所在目录下的 `config/app_config.json`,启动时同步到当前 Windows 用户注册表;运行时配置值优先读写注册表,路径为 `HKEY_CURRENT_USER\Software\Marsco\UpdateClientSDK\installations\<安装目录SHA256>\config`。如果检测到 `app_config.json` 变化,SDK 会删除 `config/client_identity.dat` 和 `config/version_policy.dat`,避免旧授权身份或旧策略继续生效;安装目录不可写时会弹出管理员权限确认框。设备身份、状态、策略、更新事务、备份、暂存文件、下载断点和 Manifest 缓存仍位于 `Launcher.exe` 所在目录下,例如 `config/client_identity.dat`、`config/local_state.json`、`config/version_policy.dat`、`update/` 和 `update_temp/`。当 SDK 放在 `SimCAE/bin` 时,这些运行时文件都在 `SimCAE/bin` 下,不会再在 `SimCAE/` 根目录生成顶层 `update/`。 -如果把软件放在 `C:\Program Files\SimCAE\bin` 并用普通用户启动,Windows 会拒绝写入,首次启动可能提示 `cannot save installation id`。当前建议先在 `D:\SimCAE_Release` 或桌面目录联调;正式要安装到 `Program Files` 时,需要补管理员提权、Windows 服务,或将运行时状态迁移到 `ProgramData` / `AppData`。 +如果把软件放在 `C:\Program Files\SimCAE\bin` 并用普通用户启动,普通配置值已经不需要写回 `app_config.json`;但设备身份、状态、策略、更新缓存等文件仍可能需要写安装目录。当前代码对小型状态文件写入已有管理员权限确认;正式要完整安装到 `Program Files` 并自动升级大文件时,后续仍建议补 Windows 服务,或将更多运行时状态迁移到 `ProgramData` / `AppData`。 ## 十一、后续待办 @@ -309,12 +339,12 @@ SimCAE/ ## 附录:原项目进度记录 -以下内容迁移自原 `client/项目进度.txt`,用于保留更详细的阶段性进度、功能清单和概念说明。 +以下内容迁移自原 `update-client/项目进度.txt`,用于保留更详细的阶段性进度、功能清单和概念说明。 ```text 软件自动升级与版本控制系统——项目进度 更新时间:2026-07-07 -依据:《软件自动升级与版本控制系统开发设计文档 v0.1》、《SimCAE_Crash_Report后端接口规范》及当前 server/client 源码 +依据:《软件自动升级与版本控制系统开发设计文档 v0.1》、《SimCAE_Crash_Report后端接口规范》及当前 update-server/update-client 源码 ============================================================ 一、项目进度概述 @@ -360,17 +390,21 @@ SimCAE 崩溃报告后端已经完成第一阶段核心接口:接收 SimCAECra 说明:MainApp 当前读取 Demo DLL 内容并显示 Hash 标识,但还没有通过 QLibrary 真正加载并调用插件接口,因此“插件实际加载”只算部分完成。 -2.2 本地 JSON 配置 +2.2 本地配置 已实现: -1. 使用 config/app_config.json 保存客户端配置。 -2. 支持旧 client.ini 自动迁移。 -3. 保存 API 地址、App ID、当前版本、渠道、设备 ID、客户端 Token、启动 Token、平台和架构。 -4. 更新成功后写入 current_version。 -5. 使用 QSaveFile 原子写入主要配置。 -6. 运行时配置不进入发布包。 -7. 已配置项目 .gitignore。 +1. 使用 `config/app_config.json` 作为部署配置源文件。 +2. Launcher / Updater / MainApp 启动时按解析后的 JSON 内容 SHA-256 判断配置是否变化,变化后自动导入当前 Windows 用户注册表。 +3. 注册表路径为 `HKEY_CURRENT_USER\Software\Marsco\UpdateClientSDK\installations\<安装目录SHA256>\config`。 +4. 后续运行配置优先从注册表读取,运行时动态值写入注册表。 +5. 检测到 JSON 变化后自动清理 `client_identity.dat` 和 `version_policy.dat`。 +6. 支持旧 client.ini 自动迁移。 +7. 保存 API 地址、App ID、当前版本、渠道、设备 ID、客户端 Token、启动 Token、平台和架构。 +8. 更新成功后写入 current_version。 +9. 文件型本地状态仍使用 QSaveFile 原子写入。 +10. 运行时配置不进入发布包。 +11. 已配置项目 .gitignore。 2.3 服务端基础能力 @@ -665,7 +699,7 @@ Updater 启动时会读取旧事务,并根据状态尝试恢复或回滚。 3. 服务端逐请求验证设备凭证、授权状态、设备禁用状态、app_id 和 channel。 4. License 授权:licenses 和 license_devices 表,支持有效期、启用/禁用、最大设备数和设备占用。 5. 授权密钥只保存 SHA-256,明文只在创建时返回一次。 -6. Launcher 首次启动时如果没有 License,会弹窗要求用户输入并自动写入配置;当前实现会先检查 `license_key` 配置项,即使本地已有 `client_identity.dat`,清空 `license_key` 仍会触发输入框。 +6. Launcher 首次启动时如果没有 License,会弹窗要求用户输入并自动写入注册表;当前实现会先检查 `license_key` 配置项,即使本地已有 `client_identity.dat`,清空 `license_key` 仍会触发输入框。 7. License 错误、过期、禁用、设备数达到上限或设备身份与授权不匹配时,Launcher 会清理旧设备身份并引导用户重新输入 License。 8. 动态渠道:channels 表按 app_id 隔离,管理后台支持新增、编辑、启用和停用。 9. 发布、策略、授权、设备登记和更新检查统一校验渠道。 @@ -1001,7 +1035,7 @@ SimCAE Crash Report 第一阶段——已实现。 8.1 服务端是什么 -服务端在 server/ 下,核心是 FastAPI 应用。它负责: +服务端在 update-server/ 下,核心是 FastAPI 应用。它负责: 1. 管理应用、版本、渠道和策略。 2. 接收管理员发布的软件文件。 @@ -1010,7 +1044,7 @@ SimCAE Crash Report 第一阶段——已实现。 5. 对 Manifest、策略、设备身份、离线包做 RSA 签名。 6. 给客户端签发临时下载 URL。 7. 接收升级结果、下载结果、设备登记和 License 授权。 -8. 提供 admin.html 管理网页。 +8. 提供新版 admin-ui 管理后台,并保留 legacy/admin.html 作为旧版兼容入口。 9. 接收 SimCAE 崩溃报告和符号包。 服务端主要存储有三类: @@ -1021,7 +1055,7 @@ SimCAE Crash Report 第一阶段——已实现。 8.2 客户端是什么 -客户端在 client/ 下,主要由几个程序配合: +客户端在 update-client/ 下,主要由几个程序配合: 1. Launcher.exe:入口程序。负责检查更新、验证策略、决定是否启动 MainApp 或 Updater。 2. Updater.exe:真正下载和安装文件的程序。负责 Manifest 验证、差异下载、断点续传、备份、校验、提交或回滚。 @@ -1320,7 +1354,7 @@ UpdateClientSDK/ 10.4 当前已有 package-client.ps1 的作用 -client/package-client.ps1 已经是 SDK/客户端包雏形。 +update-client/scripts/package-client.ps1 已经是 SDK/客户端包雏形。 它目前会做这些事: @@ -1369,7 +1403,7 @@ client/package-client.ps1 已经是 SDK/客户端包雏形。 Docker 可以理解为“把服务端运行环境打包成一个标准盒子”。 -本机直接运行 server/venv/bin/python3 main.py 时,依赖的是当前机器上的 Python 虚拟环境、当前目录、当前配置文件。 +本机直接运行 update-server/venv/bin/python3 main.py 时,依赖的是当前机器上的 Python 虚拟环境、当前目录、当前配置文件。 Docker 运行时,依赖的是镜像里的 Python、镜像里的依赖、容器里的 /app 目录和 docker-compose.yml 映射进去的数据目录。 @@ -1383,17 +1417,17 @@ Docker 运行时,依赖的是镜像里的 Python、镜像里的依赖、容器 10.7 当前服务端 Docker 已经具备什么 -当前 server/Dockerfile 已经具备: +当前 update-server/Dockerfile 已经具备: 1. 使用 python:3.12-slim 作为基础镜像。 -2. 安装 server/requirements.txt 里的 FastAPI、MinIO、cryptography 等依赖。 +2. 安装 update-server/requirements.txt 里的 FastAPI、MinIO、cryptography 等依赖。 3. 拷贝 main.py、db.py、minio_tool.py、tables.sql。 -4. 拷贝 server/admin.html 到容器内 /app/admin.html。 +4. 拷贝 update-server/legacy/admin.html 到容器内 /app/legacy/admin.html。 5. 使用非 root 用户 updateapp 运行。 6. 暴露 8000 端口。 7. 提供 healthcheck。 -当前 server/docker-compose.yml 已经具备: +当前 update-server/docker-compose.yml 已经具备: 1. minio:对象存储,保存升级文件。 2. minio-init:首次启动时创建 bucket。 @@ -1422,7 +1456,7 @@ Docker 运行时,依赖的是镜像里的 Python、镜像里的依赖、容器 示例命令: -cd server +cd update-server cp -n .env.example .env mkdir -p runtime minio_data keys docker compose config @@ -1477,8 +1511,8 @@ Docker 是给“服务端部署人员”用的。 建议下一步做两个包: -1. server/docker 部署包:给运维或服务器部署人员。 -2. client/UpdateClientSDK.zip:给其他软件开发人员。 +1. update-server/docker 部署包:给运维或服务器部署人员。 +2. update-client/UpdateClientSDK.zip:给其他软件开发人员。 10.11 现在具体怎么做 @@ -1499,14 +1533,14 @@ Docker 是给“服务端部署人员”用的。 第二步:准备客户端 SDK 包。 -1. 确认 client/out/bin 是 Release 输出目录。 +1. 确认 update-client/out/bin 是 Release 输出目录。 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 里的示例字段。 +4. 填好 update-client/config/app_config.example.json 里的示例字段。 5. 在 Windows PowerShell 执行: -cd client -.\package-sdk.ps1 -SourceDir .\out\bin -OutputDir .\dist\UpdateClientSDK -ZipFile .\dist\UpdateClientSDK.zip -SdkVersion 0.1.0 +cd update-client +.\scripts\package-sdk.ps1 -SourceDir .\out\bin -OutputDir .\dist\UpdateClientSDK -ZipFile .\dist\UpdateClientSDK.zip -SdkVersion 0.1.0 第三步:给接入方一个最小验证方式。 @@ -1521,8 +1555,8 @@ cd client SDK 是给开发者看的;具体产品给客户安装时,使用 package-client.ps1: -cd client -.\package-client.ps1 -SourceDir .\out\bin -ConfigFile .\config\app_config.json -OutputDir .\dist\UpdateClient -ZipFile .\dist\UpdateClient.zip +cd update-client +.\scripts\package-client.ps1 -SourceDir .\out\bin -ConfigFile .\config\app_config.json -OutputDir .\dist\UpdateClient -ZipFile .\dist\UpdateClient.zip 第五步:补接入方文档和 Demo。