Alibaba Cloud Linux 4 制作 Ansible RPM 包实践离线可复用背景内网 / 信创环境下无法直接访问互联网安装软件需要把 Ansible 封装成标准 RPM 包便于使用yum/dnf统一安装与离线分发。一、为什么不能直接装官方源 / EPEL 的包先确认系统基线cat/etc/os-release python3--versionls-l/usr/bin/python3.11结论如下Alibaba Cloud Linux 4Alinux 4基于 Anolis OS 23 生态默认 Python 为3.11/usr/bin/python3.11存在而不是 CentOS/RHEL 9 的 Python 3.9。官方源中没有 ansible 包。EPEL 9 中的ansibleRPM如ansible-7.7.0-1.el9.noarch按照 Python 3.9 打包在 Alinux 4 上无法安装。尝试直接下载时出现的典型报错Error: Problem: conflicting requests - nothing provides python(abi) 3.9 needed by ansible-7.7.0-1.el9.noarch - nothing provides python3.9dist(ansible-core) 2.14.7 needed by ansible-7.7.0-1.el9.noarch--nobest、--skip-broken均无法绕过因为整个依赖链都绑定 Python 3.9。EPEL 8 源同样不适用。结论Alinux 4 与 CentOS/RHEL 系组件不能直接互用需要基于 Python 3.11 自行制作 RPM。二、方案选型方案可行性说明官方源直接安装不可行官方源无 ansible 包EPEL RPM 直装 /--downloadonly不可行依赖python(abi)3.9与系统 Python 3.11 冲突EPEL 源码重打包不可行依赖链整体绑定 3.9需要全部重建工程量巨大venv pip 在线 / 离线安装可用适合单机但不是 RPM 规范无法用 yum 统一管理RPM 外壳 venv 封装推荐RPM 作为外壳内部用独立 venv pip 安装 ansible 及全部依赖满足 yum 安装规范离线可复用最终采用RPM 外壳 venv 封装方案Ansible 与全部 Python 依赖封装进独立虚拟环境/usr/lib/ansible-venv不污染系统 Python目标机只要满足python3 3.11即可直接安装。版本确认阿里云 PyPI 镜像上 ansible 最新为12.3.0要求 Python 3.11其核心依赖ansible-core~2.19.5同样要求 Python 3.11且提供py3-none-any纯 Python wheel无需编译具备打包条件。三、构建环境准备# 1. 安装构建工具与 Python 环境sudodnfinstall-yrpm-build rpmdevtools python3 python3-pip# 2. 确认 Python 3.11 与 venv 可用python3--versionpython3-mvenv--help/dev/nullechovenv OK# 3. 生成 rpmbuild 目录结构等价于手动创建 ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}rpmdev-setuptree# 4. 配置 PyPI 镜像用户级配置构建期 pip 会按该配置拉取依赖mkdir-p~/.pipcat~/.pip/pip.confEOF [global] index-url https://mirrors.aliyun.com/pypi/simple/ EOF说明pip 按全局 /etc/pip.conf → 用户 ~/.pip/pip.conf → 项目级的优先级读取配置。此处写在~/.pip/pip.conf用户级配置rpmbuild内部执行的pip install会读取同一$HOME下的配置同样生效若以 root 身份构建实际生效文件为/root/.pip/pip.conf。内网 HTTP 镜像如mirrors.cloud.aliyuncs.com可能因不受信任被 pip 忽略导致No matching distribution found for ansible建议直接使用 HTTPS 源无需trusted-host。如何在 pip 源中查询 ansible 可用版本# 1. 查看当前 pip 生效的索引地址确认配置已加载pip config list# 2. 查询 pip 源中 ansible 的全部可用版本需要 pip 23.1pip index versions ansible# 输出示例仅列出兼容当前 Python 3.11 的版本# ansible (12.3.0)# Available versions: 12.3.0, 12.2.0, 11.3.0, ...要点pip index versions ansible会按当前解释器的兼容性requires-python过滤展示可安装版本可直接确认源内最新版与可用版本列表当前为12.3.0。若系统 pip 版本过旧不支持pip index可以直接查看镜像的 simple 索引页含义相同curl -s https://mirrors.aliyun.com/pypi/simple/ansible/ | grep -oE ansible-[0-9](\.[0-9]) | sort -Vu | tail -n 20。不加版本直接pip install ansible会安装源内最新且兼容当前 Python 的版本需要固定版本时写pip install ansible12.3.0。四、编写 spec 文件保存到~/rpmbuild/SPECS/ansible.specName: ansible Version: 12.3.0 Release: 1%{?dist} Summary: Ansible is a radically simple IT automation platform License: GPL-3.0-or-later URL: https://www.ansible.com/ BuildRequires: python3 3.11 Requires: python3 3.11 %global ansible_venv %{_prefix}/lib/ansible-venv %description 基于 Python 3.11Alinux 4 系统默认构建的 ansible 所有 Python 依赖封装在 %{ansible_venv} 虚拟环境中不污染系统 Python。 %prep # 无需源码包ansible 由 pip 在 %build 阶段安装 : %build rm -rf %{_builddir}/venv python3 -m venv %{_builddir}/venv %{_builddir}/venv/bin/pip install --no-cache-dir ansible%{version} %install mkdir -p %{buildroot}%{ansible_venv} %{buildroot}%{_bindir} cp -a %{_builddir}/venv/. %{buildroot}%{ansible_venv}/ # 修正 venv/bin 下所有入口脚本的 shebang构建路径 - 最终安装路径 # grep 精确命中第一行以构建路径开头的文本脚本避免误伤二进制/软链接 grep -rl ^#!%{_builddir}/venv/bin/python %{buildroot}%{ansible_venv}/bin 2/dev/null | while read -r f; do sed -i 1s|^#!%{_builddir}/venv/bin/python.*|#!%{ansible_venv}/bin/python| $f done # 在 /usr/bin 提供 ansible* 入口 for b in %{buildroot}%{ansible_venv}/bin/ansible*; do [ -f $b ] || continue ln -s %{ansible_venv}/bin/$(basename $b) %{buildroot}%{_bindir}/$(basename $b) done %check %{buildroot}%{ansible_venv}/bin/python %{buildroot}%{ansible_venv}/bin/ansible --version %files %{ansible_venv} %{_bindir}/ansible* %changelog * Wed Oct 14 2026 筑梦之路 - 基于 Alinux 4 / Python 3.11 构建 ansible-12.3.0 venv RPM - 修正 venv 脚本 shebang消除构建路径硬依赖支持离线安装复用 - Requires 收紧为 python3 3.11五、构建# 构建前校验 spec 关键段落只出现一次防止粘贴导致重复段落的坑grep-c^%prep$~/rpmbuild/SPECS/ansible.spec# 输出必须为 1grep-c^%description$~/rpmbuild/SPECS/ansible.spec# 输出必须为 1# 构建rpmbuild-bb~/rpmbuild/SPECS/ansible.spec构建产物~/rpmbuild/RPMS/x86_64/ansible-12.3.0-1.alnx4.x86_64.rpm六、踩坑记录现象根因解决办法Error: nothing provides python(abi) 3.9EPEL 9 的 ansible 按 Python 3.9 打包与 Alinux 4 默认 Python 3.11 不兼容放弃 EPEL改用 venv 封装自建 RPMNo matching distribution found for ansible内网 HTTP pip 镜像不受信任被忽略索引为空~/.pip/pip.conf改用https://mirrors.aliyun.com/pypi/simple/warning: line 64: second Description/second %prepspec 编辑时旧文件未清理内容重复粘贴了两遍先rm -f旧 spec 再整体覆盖写入构建前grep -c校验%check阶段cannot execute: required file not found脚本 shebang 已改成最终安装路径但打包前该路径尚不存在%check显式调用 buildroot 内的python执行绕过 shebangerror: Failed dependencies: /root/rpmbuild/BUILD/venv/bin/python3 is needed by ...RPM 自动依赖扫描把 venv 脚本中残留构建机 shebang 当成安装前提旧 spec 只改了ansible*漏掉pip/pip3等脚本用grep -rl全量定位并改写所有受影响脚本的 shebangsed -i ... bin/*误伤系统 pythonvenv/bin 内含python、python3、pip等符号链接sed跟随软链误改构建机系统 Python先grep -rl精确定位纯文本脚本再逐文件sed关键点不要用rpm -ivh --nodeps绕过依赖检查——如果包内脚本的 shebang 仍是构建机旧路径即使装上也无法运行。必须把 shebang 全部改写到最终路径让依赖检查通过是顺理成章的结果。七、安装与验证# 1. 检查 RPM 依赖确认无构建机路径残留rpm-qpRansible-12.3.0-1.alnx4.x86_64.rpm期望输出只包含python3 3.11 /usr/lib/ansible-venv/bin/python # 包内自持 /usr/bin/python3.11 # 系统提供不应再出现任何/root/rpmbuild字样。# 2. 安装dnf 会自动解决 python3 依赖root 下可省略 sudosudodnfinstall./ansible-12.3.0-1.alnx4.x86_64.rpm# 3. 验证ansible--version期望显示ansible [core 2.19.5] python version 3.11.x如果构建机本身无法直连外网只有内网 PyPI 镜像也可以先在其他联网机器上用pip download缓存 wheel再在 spec 中改为--no-index --find-links安装# 联网机器上预下载全部依赖pip download-dwheelsansible12.3.0# 将 wheels/ 放入 ~/rpmbuild/SOURCES/spec 的 %build 改为# %{venv_build}/bin/pip install --no-index --find-links%{_sourcedir}/wheels ansible%{version}八、离线复用注意事项目标机系统要求python3 3.11。Alinux 4 / Anolis 23 默认满足若目标机不是同源系统venv 中指向/usr/bin/python3.11的软链可能不兼容需要按目标机环境调整或重建。不要用--nodeps强制安装依赖检查出现/root/rpmbuild路径说明包内脚本仍有构建机残留应先修 spec 重建。License 合规ansible 与 ansible-core 均为 GPL-3.0-or-laterspec 中已声明对内网分发需保留对应许可证文本。本方案同样适用于其他官方源缺失 Python 版本偏新的系统只需调整Version与Requires即可把任意纯 Python 工具打成可离线复用的 RPM。总结在 Alibaba Cloud Linux 4 上制作 ansible RPM 的关键链路是确认系统 Python 3.11 基线 → 排除 EPEL 9 的 Python 3.9 绑定包 → 采用RPM 外壳 venv 封装方案 → 用grep -rl sed全量改写 shebang 规避自动依赖扫描误判 → 构建后用rpm -qpR确认无构建机路径残留。最终产出一个可在离线内网环境用dnf install一键安装、且不污染系统 Python 的标准 RPM 包。
阅读完成 · 觉得有帮助?