Skip to content

Latest commit

 

History

History
89 lines (70 loc) · 6.07 KB

File metadata and controls

89 lines (70 loc) · 6.07 KB

💡 Mock 项目修复历程与配置差异总结

本文档旨在阐明 Vehicle_Mock_fixed 项目从最初的问题诊断到最终成功部署的全过程,并详细解释为什么我们当前的 Dockerfile.github/workflows/*.yml 文件与公司原始仓库的配置存在差异。


1. 最终运行时错误修复 (ModuleNotFoundError: No module named 'jaraco')

最终问题:

在 OWA5X 设备上运行新构建的 vehicle-mock 镜像后,容器立即退出,日志显示以下错误:

ModuleNotFoundError: No module named 'jaraco'
[9] Failed to execute script 'pyi_rth_pkgres' due to unhandled exception!

🔬 根本原因:

  • PyInstaller 的静态分析局限PyInstaller 在打包Python应用时,会分析代码找出所有依赖项。但它无法完美处理所有动态导入或隐藏的依赖。
  • pkg_resources 的隐藏依赖pkg_resources 这个库(setuptools 的一部分)在运行时会动态加载 jaraco 系列的模块。PyInstaller 未能自动检测到这个“隐藏”的依赖关系。
  • 结果:打包出的 run-exe 可执行文件中缺少了 jaraco 模块,导致容器一启动就因找不到模块而崩溃。

解决方案:

我们通过修改 Dockerfile,在 pyinstaller 命令中明确告知它需要包含这些缺失的模块。

vehicle-mock/Dockerfile (第 47 行):

# 原始命令
# RUN pyinstaller --clean -F -s --paths=src mockprovider.py

# 修复后的命令
RUN pyinstaller --clean -F -s --paths=src \
    --hidden-import jaraco.text \
    --hidden-import jaraco.functools \
    --hidden-import jaraco.context \
    mockprovider.py
  • --hidden-import:这个参数强制 PyInstaller 将指定的模块打包进最终的可执行文件,从而解决了运行时的 ModuleNotFoundError

2. 为什么我们的配置与原始Repo不同?—— 一步步的演变史

我们的目标是修复 vehicle-mock 的核心问题,并建立一个可靠、独立的CI/CD流程。这个过程经历了几个阶段,导致了配置上的差异。

阶段一:初始目标 - 修复灯光冲突 & 建立独立CI

  • 核心任务:解决 vehicle-mock 覆盖 ExteriorLightControl 信号导致灯光控制冲突的问题。
  • CI/CD 目标:创建一个能在你自己的GitHub仓库 (Vehicle_Mock_fixed) 中自动构建和发布镜像的现代化工作流(Workflow)。
  • 最初的修改
    1. 注释掉 vehicle-mock/app/mock.py 中关于 ExteriorLightControl 的代码。
    2. 创建了新的 .github/workflows/ 文件,支持 multiarch (amd64 + arm64) 构建,比原始仓库仅支持 arm64 更先进。

阶段二:首次构建失败 - SCons 模块未找到

  • 问题:当我们尝试进行 multiarch 构建时,arm64 平台的构建失败了。
  • 错误信息ModuleNotFoundError: No module named 'SCons'
  • 原因
    • 在GitHub Actions的 QEMU模拟arm64环境 中,staticx 库没有预编译包,需要从源码构建。
    • staticx 的源码构建依赖 SCons 工具。
    • pip 默认使用“构建隔离”(build isolation),它会创建一个临时、干净的环境来构建包。这个隔离环境看不到我们在上一步用 apt-get 安装的 SCons
  • 当时的解决方案
    • Dockerfile 中为 staticx 的安装命令添加 --no-build-isolation 参数。这使得 pip 可以在系统环境中构建,从而找到 SCons

阶段三:策略调整 - 与原始Repo对齐

  • 你的要求:你提出只需要构建 arm64,并希望配置能和公司原始仓库尽可能保持一致。
  • 我们做的修改
    1. 修改 Workflow (.yml 文件)
      • multiarch 构建目标改回了固定的 platform: "linux/arm64"
      • 将镜像标签从动态生成(如 :latest, :sha)改为了固定的 :v001arm
    2. 回退 Dockerfile
      • 我们撤销了在阶段二中对 Dockerfile 的修复(移除了 --no-build-isolation--hidden-import),使其与原始文件一模一样。
  • 结果构建再次失败! 错误和阶段二完全相同 (SCons not found)。

阶段四:真相大白与最终修复

  • 结论:我们终于明白,公司原始仓库的 Dockerfile 本身就存在缺陷。它无法在GitHub Actions的QEMU模拟环境中成功构建 arm64。它之所以在公司内部能成功,可能是因为:
    • 使用了自托管的、真实的ARM64硬件作为Runner。
    • 或者在某个特定的时间点,staticx 恰好有可用的预编译包。
  • 最终的正确配置
    1. 恢复 Dockerfile 的修复:我们再次将 --no-build-isolation--hidden-import 添加回 Dockerfile。这两个修复是确保在任何标准CI环境中都能成功构建和运行的必要条件
    2. 保持 Workflow 的精简:我们保留了只构建 arm64 的配置,以满足你的最终需求。

📊 总结:差异的核心原因

配置差异点 原始 Repo 你的 Repo (最终版) 为什么不同?
Dockerfile 有缺陷,缺少构建参数 已修复 原始文件无法在GitHub Actions的QEMU模拟环境中构建arm64。你的版本通过添加 --no-build-isolation--hidden-import 修复了构建时运行时的错误,使其更健壮、更通用。
Workflow (.yml) 深度集成Velocitas,路径复杂 已简化 你的Workflow被简化,去除了不必要的Velocitas依赖和复杂的路径,使其更独立、更易于维护,专注于核心的“构建-推送”任务。
构建目标 硬编码 arm64 硬编码 arm64 这一点最终保持了一致,以满足你在OWA5X设备上部署的直接需求。

总而言之,你的配置文件与原始仓库不同,是因为我们不仅修复了应用本身的逻辑错误,还修复了其CI/CD流程中潜藏的构建和运行时缺陷,最终形成了一套更可靠、更健壮的自动化流程。