Ansible ansible-core 开发环境搭建:可编辑安装、hacking/env-setup 与免安装运行 ansible-test
本文聚焦 ansible-core 开发环境搭建指南:说明在 POSIX 环境(Windows 下需 WSL)中完成 ansible-core 及全部 CLI 的开发环境配置的三种方式——pip install -e . 可编辑安装、source hacking/env-setup 环境变量注入、以及不安装直接调用 bin/ansible-test 运行测试,并结合仓库内的 pyproject.toml、requirements.txt、hacking/env-setup 和 bin/ansible-test 等文件,解释每种方式在底层到底做了什么、各自的适用场景与限制。
1. 平台前提:POSIX 系统与 WSL
开发环境文档开宗明义:
ansible-core and all CLIs (including ansible-test) require a POSIX OS. On Windows, use WSL (Windows Subsystem for Linux).
即:ansible-core 本体与它提供的全部命令行入口(包括测试工具 ansible-test)都必须在 POSIX 操作系统上运行。在 Windows 平台上开发,官方建议的做法是使用 WSL(Windows Subsystem for Linux),而不是在 Windows 原生环境里运行。这与 pyproject.toml 中的元数据声明一致——classifiers 里明确标注了 "Operating System :: POSIX",且 requires-python = ">=3.13",即当前开发主干要求 Python 3.13 或更高版本(classifiers 中列出的受支持解释器版本为 3.13 / 3.14 / 3.15)。
此外,当前仓库的版本号定义在 lib/ansible/release.py 中(__version__ = '2.22.0.dev0'),说明这是一个开发中版本的主干检出,适合用于开发调试而非生产部署。
2. 方式一:可编辑安装(pip install -e .)
文档推荐的默认做法是:fork 并 clone 仓库后,在仓库根目录执行可编辑(editable)安装:
pip install -e .
可编辑安装意味着包不会被复制进 site-packages,而是直接指向仓库的源码目录,之后修改源码无需重新安装即可生效——这正是日常开发所期望的行为。
结合 pyproject.toml 可以看到这条命令实际会完成的事:
- 构建后端:
[build-system]指定setuptools >= 77.0.3, <= 80.3.1作为构建依赖,使用setuptools.build_meta后端。 - 打包范围:
[tool.setuptools.packages.find]的where = ["lib", "test/lib"]表明包发现同时覆盖lib/(运行时代码)与test/lib/(ansible-test相关代码),二者都会被装入环境。 - 版本与依赖的动态解析:
[tool.setuptools.dynamic]从ansible.release.__version__属性读取版本号,并从 requirements.txt 读取运行时依赖。 - CLI 入口点:
[project.scripts]一次性注册了 10 个可执行命令,包括ansible、ansible-config、ansible-console、ansible-doc、ansible-galaxy、ansible-inventory、ansible-playbook、ansible-pull、ansible-vault,以及ansible-test(其入口指向ansible_test._util.target.cli.ansible_test_cli_stub:main)。安装完成后,这 10 个命令会进入PATH,可以直接在任意目录调用。
运行时依赖清单见 requirements.txt,文件头部注释也说明了其定位——这是“让包能运行的最宽松集合”:
| 依赖 | 版本约束 | 说明 |
|---|---|---|
| jinja2 | >= 3.1.0 |
3.1.0 起才修复了 Jinja2 native macro 支持 |
| PyYAML | >= 5.1 |
Python 3.8+ 支持所需 |
| cryptography | 无下限约束 | 加解密相关能力 |
| packaging | 无下限约束 | 版本解析工具 |
| resolvelib | >= 0.8.0, < 2.0.0 |
ansible-galaxy 使用的依赖求解器;注释提醒 0.x 的版本跳动应视为破坏性变更,升级上限需谨慎,并需同步更新 ansible-galaxy-collection 测试套件中使用的最新版本 |
3. 方式二:source hacking/env-setup,免安装注入环境
如果不想把当前检出装进 Python 环境,文档给出的替代方案是:
source hacking/env-setup
注意这里必须是 source(在当前 shell 内执行)而非直接运行,因为脚本的生效机制是修改当前 shell 的环境变量。阅读 hacking/env-setup 源码(一个 POSIX sh 脚本,文件头注释 usage: source hacking/env-setup [-q] 也明确了用法),它具体做了以下几件事:
- 定位仓库根目录:脚本兼容 bash(
$BASH_SOURCE)、ksh93(.sh.file)、ash 等多种 shell,解析出hacking/的父目录并通过os.path.realpath取得真实路径,导出为ANSIBLE_DEV_HOME。 - 注入四个环境变量(通过
prepend_path函数,已存在则跳过,避免重复前缀):PYTHONPATH前置lib/和test/lib/——让python直接导入检出中的ansible与ansible_test包;PATH前置bin/——仓库根目录下的bin/已包含 ansible、ansible-playbook、ansible-test 等 10 个命令行入口;MANPATH前置docs/man。
- 清理字节码缓存:递归删除仓库内所有
*.pyc文件,防止旧的编译缓存干扰源码修改后的行为。 - 可选静默模式:传
-q时 verbosity 降为silent,不打印最终的PATH/PYTHONPATH/MANPATH汇总(默认info级别会打印“Setting up Ansible to run out of checkout...”提示块)。
仓库中还提供了一个 hacking/env-setup.fish,说明该机制同样面向 fish shell 用户(POSIX 版脚本针对 bash/ksh/ash,fish 语法不兼容,因此需要单独的 fish 版本)。
可以推断:这种“免安装”方式适合临时验证、代码审查或不想污染 Python 环境的场景;代价是每次新开 shell 都要重新 source,并且依赖 python3 已在 PATH 中(脚本内用 command -v python3 || command -v python 探测)。
4. 方式三:完全不安装,直接跑 bin/ansible-test
文档指出:如果只需要跑测试,连 hacking/env-setup 都不必 source,可以直接调用:
bin/ansible-test sanity -v --docker default
这里的关键是 bin/ansible-test 这个入口脚本的行为(它本身就是一个 Python 文件):
- 优先使用源码树版本:
main()计算仓库根后检查test/lib/ansible_test/_internal/__init__.py是否存在,若存在则把test/lib插入sys.path首位,注释明确说明目的是“running from source, use that version of ansible-test instead of any version that may already be installed”——从源码运行时用检出中的ansible-test,而不是环境里可能已安装的版本。 - Python 版本闸门:随后导入
CONTROLLER_PYTHON_VERSIONS(定义在 test/lib/ansible_test/_util/target/common/constants.py,为3.13/3.14/3.15),当前解释器不在其中则直接SystemExit并列出支持的版本。 - 文件句柄检查:
stdin/stdout/stderr必须是阻塞模式,否则拒绝运行。 - 最后转入
ansible_test._internal.main启动真正的 CLI。
关于 sanity 子命令的参数与容器用法,可进一步参考姊妹文档 running-tests.md:--docker 不带参数时默认使用 default 容器(本文档中的 --docker default 即等价于 --docker);base / default 容器仅适用于 sanity/units 测试,集成测试应使用发行版专用容器(如 --docker ubuntu)。sanity 测试本身支持脱离容器本地运行,只是本地缺失 shellcheck、PowerShell 或额外 Python 版本等依赖时部分检查会被跳过,因此文档示例才用 --docker default 以获得完整覆盖。
5. 三种方式怎么选
| 方式 | 命令 | 需要 pip 安装 | 需要每次 source | 适用场景 |
|---|---|---|---|---|
| 可编辑安装 | pip install -e . |
是 | 否 | 长期开发,需要完整的 ansible 全套 CLI 入口点 |
| 环境变量注入 | source hacking/env-setup |
否 | 是(每个新 shell) | 临时开发/验证,不想修改 Python 环境 |
| 免安装跑测试 | bin/ansible-test sanity -v --docker default |
否 | 否 | 只跑测试、只验证改动 |
三者都建立在同一个前提之上:POSIX 系统(Windows 下用 WSL)、Python 3.13+,且在仓库根目录内操作。更完整的测试命令参考(units、integration、容器选择、--venv 隔离选项等)见 context/running-tests.md,开发目录的整体背景(面向人类与 Agent 的 ansible-core 开发上下文索引)见 context/README.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00