Files
update-client/docs/legacy-configuration-migration.md
T
Comely fe5aa5bbf0 feat(hardening): 内嵌产品配置 + 系统级状态 + 全量 i18n + 依赖治理 + 资料清理
update-client-hardening 四工作流合入(构建/静态检查已过):

- 配置:不可变产品策略经 UpdateClientResources.cmake 归一化校验后
  内嵌 qrc(URL/相对路径/主程序必须落 install_root/版本/UUID 格式,
  CMake override 写入前复验);可变机器状态迁系统级原生存储;
  运行目录不再落可编辑 app_config.json。
- i18n:生产源全英文(no-Han 检查 41/41),中文进 translations/
  zh_CN 目录;翻译加载收敛 Common/TranslationHelper 唯一入口;
  Bootstrap 补资源文件。
- 依赖:Qt/OpenSSL/架构/Perl 机器路径改 imported targets +
  UpdateClientDependencies.cmake,3rdparty 由父工程契约供给。
- 清理:旧 README/SDK README/3 个重复 PowerShell 打包脚本/PDF 提取
  文本删除,canonical README + 5 份结构化英文文档替代;Launcher
  requireAdministrator manifest;统一 MSVC /utf-8 删运行时编码设置。
2026-07-10 00:38:23 -07:00

5.6 KiB

Legacy 配置迁移

范围

较旧的 update-client 构建版本会读取并重写可执行文件旁边的 product 数据。在升级安装中,可能存在两种格式:

  • config/app_config.json; 和
  • client.ini

新版本使用嵌入式产品配置加上本地机器范围的状态存储。旧文件仅作为迁移输入,它们永远不会覆盖嵌入式应用程序标识、服务器端点、通道、可执行策略或票据配置。

此迁移与配置时的 config/config.json 无关。后者是受控的源代码树或构建流水线输入,从不会从安装中读取。

迁移优先级

迁移仅在原生状态存储尚未为此产品安装完成迁移时运行。

  1. 现有有效的原生状态胜利,且不读取遗留文件。
  2. 否则,导入允许的可变值 config/app_config.json 在存在且有效时。
  3. client.ini 中填充仍缺失的允许值(当存在时)。
  4. 验证导入的值并将它们原子性地持久化到原生存储中。
  5. 仅在状态写入成功后记录迁移完成。

迁移必须是幂等的。对旧文件的后续编辑不应改变已迁移的安装。

允许的值

只能导入可变的安装状态:

旧值 新所有者 迁移规则
current_version 原生安装版本状态 从未签名的旧文件中导入;从嵌入的构建状态初始化,并且仅通过经过验证的更新事务进行升级。
license_key Native enrollment state Import as enrollment input; the server still validates it.
device_id 原生设备状态 当有有效签名设备凭证时,优先使用其值。
installation_id 原生安装状态 仅在语法有效时导入;否则通过当前状态服务生成。
单调策略/更新标记 原生状态或签名缓存 仅通过专用验证导入;永远不要信任未签名的较低序列。

迁移时不得将这些遗留值作为运行时覆盖导入:

  • app_idapp_name;
  • channelclient_protocol;
  • api_base_urlclient_token;
  • launch_token;
  • 可执行文件名或 install_root;
  • 临时目录布局;
  • 平台或架构;或
  • 请求和健康检查策略。

这些值只能来自构建期间选择的嵌入式产品配置。

旧版 INI 映射参考

旧的 INI 格式将值分组如下。此表仅用于支持有限的迁移阅读器和法医诊断。

Section Keys previously used
App app_id, app_name, channel, current_version, client_protocol, launch_token
许可协议 license_key
服务器 api_base_url, client_token
更新 request_timeout_ms, temp_folder, device_id
设备 installation_id
运行时 install_root, main_executable, launcher_executable, updater_executable, bootstrap_executable, health_check_timeout_ms

只有上述可变子集可能离开此解析器。该表不会将其他键识别为支持的设置。

验证与失败

  • 解析旧版 JSON 和 INI 文件而不更改文件内容。
  • 在编写本地状态之前,应用严格的长度和格式检查。
  • 不要将未签名的策略序列向后复制。
  • 不要将遗留路径接受为可执行文件或更新根。
  • 将所有导入的状态原子地写入,然后设置迁移完成标记。
  • 如果持久化失败,请报告一个可操作的错误并保留迁移未完成状态,以便在权限或存储问题解决后可以重试。
  • 不要在每次启动时都回退到读取旧文件。

格式错误的旧文件不得阻止干净安装与当前产品配置的注册。保留足够的诊断信息以识别被拒绝的来源,但不要显示许可证材料或客户端令牌。

已签名的旧文件

旧的安装可能还包含:

  • config/client_identity.dat;
  • config/version_policy.dat;
  • config/local_state.json; 和
  • update/manifest_cache/

这些不是产品配置。只有在当前签名、身份、通道、版本、过期时间和防回滚检查通过后,才能重复使用已签名的设备凭证、策略或清单。未签名的本地状态只是一个迁移提示,不能降低已记录的序列号或延长离线有效性。

迁移实现应将接受的状态移动到当前批准的存储或缓存位置。它不得继续将可执行目录视为可写运行时数据库。

打包规则

父级 package_installer 输出中不得包含遗留配置或状态。特别是,不要打包:

  • app_config.json;
  • client.ini;
  • 开发机器的设备凭证;
  • 本地策略状态;
  • 交易状态;或
  • 更新下载和备份目录。

存在迁移代码用于从旧版本升级,而不是为了维持旧的软件包结构。

操作规程

对于现有安装:

  1. 通过受支持的安装程序/更新路径安装已签名的新包。
  2. 通过 Launcher 启动,并使用原生机器状态所需的平台权限。
  3. 确认设备注册、策略验证和已安装版本状态。
  4. 确认第二次启动成功,无需查阅已更改的旧文件。
  5. 确认直接应用启动仍被阻止。

迁移成功后,旧文件可以归档用于事件分析,或通过批准的清理路径删除。它们的持续存在不应影响运行时策略。

迁移测试

覆盖至少:

  • 无遗留文件的干净安装;
  • 仅 JSON 迁移;
  • 仅 INI 迁移;
  • JSON 优先,INI 作为缺失可变值的后备;
  • 现有原生状态带有恶意的遗留覆盖;
  • 格式错误的 JSON 和格式错误的 INI 值;
  • 无效或过期的签名遗留凭证;
  • 原生状态写入失败后成功重试;
  • 迁移完成后重复启动;以及
  • 迁移后的侧车配置被篡改。