Pants构建files_service时BinaryNotFoundError问题求助
我用Pants管理一个单体仓库,仓库内所有服务的构建文件和应用结构完全一致,但只有files_service服务无法正常打包:
- 执行
pants run可以成功启动files_service - 执行
pants package构建files_service-bin时,出现BinaryNotFoundError,提示找不到unzip,但本地环境明明已安装unzip(路径/usr/bin/unzip)
错误日志
Engine traceback:
inpackagegoalBinaryNotFoundError: Cannot find
unzipon['/bin', '/opt/homebrew/bin', '/usr/bin', '/usr/local/bin']. Please ensure that it is installed so that Pants can download the tools Pants needs to run.
特殊背景
该服务是仓库中唯一以服务端形式实现Proto接口的服务,Proto定义目录的BUILD配置如下:
protobuf_sources( name="protos", sources=[ "files/v1/chat.proto", "files/v1/backups.proto", ], grpc=True, )
服务BUILD文件配置
python_sources( name="files_service", sources=["**/*.py"], dependencies=[ ":files_service-reqs" ] ) python_requirements( name="files_service-reqs" ) pex_binary( name="files_service-bin", output_path="files_service/package/binary.pex", execution_mode="venv", entry_point="files_service.main", include_sources=True, include_tools = True, dependencies=[ ":files_service" ] ) docker_image( name = "sherlock-ai-files_service-image", dependencies=[ ":files_service-bin" ] ) python_test_utils( name="files_service-test-utils", sources=[ "**/conftest.py", ], dependencies=[ ":files_service" ] ) python_requirements( name="files_service-test-reqs", source="pytest-requirements.txt", resolve="pytest" ) python_tests( name="files_service-tests", sources=[ "tests/**/test_*.py", "!**/conftest.py", ], dependencies=[ ":files_service-test-utils", ":files_service" ] )
pants.toml配置
[GLOBAL] pants_version = "2.22.0" colors = true backend_packages = [ "pants.core", "pants.backend.python", "pants.backend.codegen.protobuf.python", "pants.backend.build_files.fmt.ruff", "pants.backend.experimental.python.lint.ruff.check", "pants.backend.experimental.python.typecheck.pyright", "pants.backend.docker" ] concurrent = true [source] root_patterns = [ "src", "libs" ] [environments-preview.names] local_linux = "//:local_linux" local_osx = "//:local_osx" docker = "//:docker" [python] interpreter_constraints = [ ">=3.11,<3.13" ] enable_resolves = true [python.resolves] python-default = "python-default.lock" pytest = "pytest-default.lock" [python-protobuf] mypy_plugin = true [test] output = "all" report = false use_coverage = true [coverage-py] global_report = true [pytest] install_from_resolve = "pytest" args = ["-vv", "-s", "-W ignore::DeprecationWarning", "--no-header"]
根目录BUILD文件配置
__defaults__({ pex_binary: dict( environment="local_linux", tags=["binary"] ), docker_image: dict( build_platform=["linux/amd64"], tags=["docker"] ), }) local_environment( name="local_linux", compatible_platforms=["linux_x86_64"], fallback_environment="docker" ) local_environment( name="local_osx", compatible_platforms=["macos_arm64"], ) docker_environment( name="docker", platform="linux_x86_64", image="python:3.12-slim" )
系统与环境信息
- 系统版本:
~ % sw_vers ProductName: macOS ProductVersion: 14.0 BuildVersion: 23A344 unzip路径:~ % which unzip /usr/bin/unzip
修复Docker环境依赖缺失
files_service-bin默认使用local_linux环境,该环境的 fallback 是基于python:3.12-slim镜像的docker环境,而slim镜像默认未安装unzip,Pants在容器内执行打包时找不到工具导致报错。其他服务可能未触发Docker fallback,或依赖镜像已包含unzip。
解决方法:修改docker_environment配置,添加安装unzip的步骤:docker_environment( name="docker", platform="linux_x86_64", image="python:3.12-slim", setup_commands=[ "apt-get update && apt-get install -y unzip && rm -rf /var/lib/apt/lists/*" ] )强制使用本地OSX环境打包
若不需要跨平台打包,可临时指定本地环境执行命令:pants package --environment=local_osx //path/to/files_service:files_service-bin或修改服务的
pex_binary配置,固定使用本地环境:pex_binary( name="files_service-bin", # 保留原有其他配置 environment="local_osx" )验证Pants执行时的PATH变量
尽管本地unzip路径正确,但Pants执行时的PATH可能被修改。可在pants.toml中强制指定完整PATH:[GLOBAL] extra_env_vars = ["PATH=/usr/bin:/bin:/opt/homebrew/bin:/usr/local/bin"]
内容的提问来源于stack exchange,提问作者aleksv

