[RHEL8] 指定rpm软件包的更高版本模块流
背景:挂载RHEL ISO使用kickstart安装操作系统,安装包未指定安装perl,但是安装完可以查到其版本,且安装的是ISO中多个版本中的最低版本。
原因:(1)为什么没有装perl,perl -v可以看到版本?
因为安装perl其它包而安装了perl-libs等
如何找到是哪个包依赖了perl-libs等?
- 针对包组,查看@core里装哪些包 dnf groupinfo core -> 排除是这里面默认装的
- 针对指定包,查看其它指定包依赖于哪些包,例如perl-xxx
查看依赖关系的命令
dnf repoquery –requires <pkg name> 查看指定包依赖于哪些包
dnf repoquery –whatrequires <pkg name> 查看哪些包依赖于指定包
dnf repoquery --help | grep require
[--whatrequires REQ] [--whatrecommends REQ]
[--conflicts | --depends | --enhances | --provides | --recommends | --requires | --requires-pre | --suggests | --supplements]
--whatdepends REQ shows results that requires, suggests, supplements,
--whatrequires REQ shows results that requires package provides and files
--recursive used with --whatrequires, and --requires --resolve,
--requires Display capabilities that the package depends on.
--requires-pre If the package is not installed display capabilities
--recursive used with --whatrequires, and --requires --resolve,
query packages recursively.
[root@xxx ~]# dnf repoquery --requires perl-DBD-SQLite-1.58-2.module+el8.6.0+13408+461b4ab5.x86_64
Updating Subscription Management repositories.
Unable to read consumer identityThis system is not registered with an entitlement server. You can use subscription-manager to register.Last metadata expiration check: 2:02:32 ago on Sat 15 Mar 2025 01:18:35 PM CST.
libc.so.6(GLIBC_2.14)(64bit)
libperl.so.5.32()(64bit)
libpthread.so.0()(64bit)
libpthread.so.0(GLIBC_2.2.5)(64bit)
libsqlite3.so.0()(64bit)
perl(:MODULE_COMPAT_5.32.1)
perl(:VERSION) >= 5.6.0
perl(DBD::SQLite)
perl(DBD::SQLite::VirtualTable)
perl(DBI) >= 1.57
perl(DynaLoader)
perl(Exporter)
perl(Scalar::Util)
perl(Tie::Hash)
perl(base)
perl(constant)
perl(locale)
perl(strict)
perl(warnings)
rtld(GNU_HASH)
(2)为什么安装的是最低版本
RHEL 8 使用 模块化(modular)仓库,某些软件包(如 perl-libs)属于 应用流(AppStream),系统会默认启用某个流(stream)。Kickstart 默认安装的软件包可能受 默认模块流 影响,而非安装最高版本。
解决方案:
指定好repo,例如将iso挂载到/mnt,编辑os.repo
# cat /etc/yum.repos.d/os.repo
...[rhel-baseos]
name=RHEL8
baseurl=file:///mnt/BaseOS
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release[rhel-appstream]
name=RHEL8
baseurl=file:///mnt/AppStream
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
执行 dnf clean all
查看 dnf repolist
# dnf repolist
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered with an entitlement server. You can use subscription-manager to register.
repo id repo name
rhel-appstream RHEL8
rhel-baseos RHEL8
重置并启用指定模块的最新流
dnf module reset -y perl
dnf module enable -y perl:5.32
dnf distro-sync -y
说明:
dnf module reset 清除默认模块流,防止使用默认的旧版本。
dnf module enable 指定最新版本的模块流。
dnf distro-sync 确保所有包同步到最高版本。
=================================================
附1:
RHEL 8 本地 RPM 升级(包括模块化包)完整步骤
适用于 从本地目录升级 RPM 包,确保 模块化包(AppStream)使用较新版本。
步骤 1:准备本地升级包
将所有 需要升级的 RPM 包放在一个目录,例如:
mkdir -p /var/update-packages
cp /path/to/rpms/*.rpm /var/update-packages/
步骤 2:创建本地仓库
RHEL 8 需要 createrepo_c 来索引 RPM 包:
dnf install -y createrepo_c
cd /var/update-packages/
createrepo_c .
如果包含 模块化包(AppStream),还需要 处理 module metadata:
# cd /var/update-packages/
# repo2module -s stable /var/update-packages/
# modifyrepo_c --mdtype=modules modules.yaml repodata/
步骤 3:配置本地 repo
在 /etc/yum.repos.d/local.repo 添加以下内容:
[local-updates]
name=Local Update Repo
baseurl=file:///var/update-packages/
enabled=1
gpgcheck=0
然后执行:
dnf clean all
dnf makecache
步骤 4:重置 & 启用模块
dnf module reset -y perl python nodejs
dnf module enable -y perl:5.32 python:3.9 nodejs:18
步骤 5:执行升级
dnf upgrade --disablerepo=* --enablerepo=local-updates -y
步骤 6(可选):检查结果
dnf list installed | grep perl
dnf module list | grep '[e]'
=================================================
附2:chatGPT提问记录
Q: 哪些软件涉及模块流?
RHEL 8+ 里,涉及模块流的软件通常是:
- 编程语言:
- perl(5.26, 5.30, 5.32)
- python(3.6, 3.8, 3.9, 3.11)
- nodejs(10, 12, 14, 16, 18)
- ruby(2.5, 2.6, 2.7, 3.0)
- php(7.2, 7.3, 7.4, 8.0)
- gcc-toolset(9, 10, 11, 12)
- 数据库:
- postgresql(9.6, 10, 12, 13, 14)
- mariadb(10.3, 10.5)
- Web 服务器 & 代理:
- httpd(Apache HTTP Server)
- nginx
- varnish
- 消息队列:
- redis
- rabbitmq
- 其他开发工具:
- llvm-toolset
- subversion
Q: 如何查看系统里有哪些模块流?
dnf module list --all
- [d] 代表默认启用的模块流(default)
- [e] 代表已启用的模块流(enabled)
# dnf module list
Updating Subscription Management repositories.
Unable to read consumer identityThis system is not registered with an entitlement server. You can use subscription-manager to register.@modulefailsafe
Name Stream Profiles Summary
perl 5.26 [e] common, minimal Practical Extraction and Report Language
perl-DBD-SQLite 1.58 [e] common SQLite DBI driver
perl-DBI 1.641 [e] common A database access API for Perl
perl-IO-Socket-SSL 2.066 [e] common Perl library for transparent TLS
perl-libwww-perl 6.34 [e] common A Perl interface to the World-Wide Web
x86_64 stable [e] everything <auto-generated module summary>Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
说明:
Name 列:模块名称,如 perl、perl-DBI 等。
Stream 列:已启用的模块流(版本),例如:
Profiles 列:模块的 可选配置,如 common, minimal。
Summary 列:简要描述。
perl 5.26 [e]
[e] 代表 已启用(enabled),表示当前 dnf 只能从这个流 安装 perl 相关包。
perl 5.26 已启用,所以无法直接安装 perl 5.32,需要先 dnf module reset perl,然后 dnf module enable perl:5.32。
@modulefailsafe
说明 dnf 处于“failsafe”模式,因为你的系统没有 Red Hat 订阅(RHSM 未注册)。
这意味着 dnf 只能使用 本地已启用的模块流,不会尝试访问外部仓库。
Q: 为什么环境装了python3.12 却不能在dnf module list里查到
- AppStream 里有两种类型的软件包:
- 模块化软件包(module-based),可以使用 dnf module 管理,例如 perl, nodejs, python:3.9。
- 非模块化软件包(普通 RPM 包),可以直接用 dnf install 安装,例如 python3.12。
- python3.12 可能是 AppStream 里的普通 RPM 包,而不是模块流,所以 dnf module list 里不会列出来。RHEL 8 默认的 Python 模块流最高是 python:3.9
Q: 查看某个rpm包来自哪个仓库
dnf repoquery --info python3.12
Name : python3.12 Version : 3.12.1 Release : 4.el8 Architecture : x86_64 Size : 29 k Source : python3.12-3.12.1-4.el8.src.rpm Repository : rhel-appstream Summary : Version 3.12 of the Python interpreter URL : https://www.python.org/ License : Python Description : Python 3.12 …… |
dnf module list python
[root@testVM1 ~]# dnf module list | grep python libselinux-python 2.8 common Python 2 bindings for libselinux python27 2.7 [d] common [d] Python programming language, version 2.7 python36 3.6 [d] build, common [d] Python programming language, version 3.6 python38 3.8 [d] build, common [d] Python programming language, version 3.8 python39 3.9 [d] build, common [d] Python programming language, version 3.9 [root@testVM1 ~]# |