RPM 无法遵循安装时的依赖顺序

RPM fails to follow dependency order on install

我试图强制 rpm 遵循给定的安装顺序,但它没有按预期工作。我添加的 Requires 子句没有得到遵守。

我正在做裸机 Linux 安装程序(基于 openSUSE 42.2)。整个系统——数百个包——用一个 RPM 命令安装(使用 --root)。我在使用三个包时遇到了问题——pam-config、pam-script 和 openssh。 pam-config %post scriptlet 尝试修改 pam-script 和 openssh 中包含的文件,但默认情况下在它们之前安装。默认情况下它没有依赖关系,因此,有了源代码,我通过添加来纠正它:

Requires: pam-script
Requires: openssh

pam-config.spec。 (我也尝试了 Prereq:,结果相同。)正如预期的那样,通过此更改,它切换了 pam-script 的顺序并且该错误消失了。但它坚决拒绝改变openssh的安装顺序,在pam-config之后安装两个包。 [Openssh 依赖于 coreutils 和 shadow (pwdutil),此时两者都已安装。它还依赖于 (PreReq) 一个神秘的宏 %{fillup_prereq}.]

其他所有安装(和运行)都很好,但我想更好地了解 rpm 的工作原理。我想如果我在 pam-config 中使用 Required: 指定 openssh,那么 openssh 总是会在 pam-config 之前安装。它适用于 pam 脚本。

rpm -qp --requires.rpm 文件上显示 openssh。我使用 -vv 选项而不是 -v 重复安装。我可以看到列出的 openssh 的 Requires: 与 pam-script (YES (added provide)) 一样。我看到 pam-config-0.91xxx -> openssh-7.2p2xxx 列在 SCC #8: 11 members (100 external dependencies) 下。我看到了 pam-config 的安装,它没有依赖信息,除了生成错误 (pam-config --service sshd --delete --listfile) 的 %post scriptlet 命令之外没有什么特别之处。我应该查看哪些其他类型的东西来调试它?这些 SCC 是什么?我是否遗漏了有关 Requires 的内容?或者是否有一些我可能忽略的晦涩的东西,比如循环、间接或隐藏的依赖关系(我已经检查过,但排除了它)?我看过几个 RPM 教程并进行了一些网络搜索,但一无所获。

UPDATE:看来与 pam-script 不同,openssh 陷入了相互依赖的临界区。这是实际安装的软件包的顺序:

ruby2.1-rubygem-ruby-dbus-0.9.3-4.3.x86_64.rpm
pam-script-1.1.6-1.os42.gb01.x86_64.rpm
suse-module-tools-12.4-3.2.x86_64.rpm
kmod-17-6.2.x86_64.rpm
kmod-compat-17-6.2.x86_64.rpm
libcurl4-7.37.0-15.1.x86_64.rpm
pam-config-0.91-1.2.os42.gb01.x86_64.rpm
systemd-sysvinit-228-15.1.x86_64.rpm
krb5-1.12.5-5.13.x86_64.rpm
openssh-7.2p2-6.1.SBC.os42.gb01.x86_64.rpm
dracut-044-12.1.x86_64.rpm
systemd-228-15.1.x86_64.rpm

如果我在生产系统上进行安装并在 pam-config 之前停止,它会抱怨依赖于 krb5,这是未来的事!如果我停在 ruby,它就会工作。如果我停在 pam-script,它就可以工作。如果我在 suse-module-tools 处停止,它会抱怨对 dracut 的依赖性。所以我想知道 RPM 是否在相互依赖的关键部分中放弃了它的排序原则,或者是否存在我尚未发现的依赖关系。我正在使用 rpm -q --requiresrpm -q --provides 来解决这个问题。敬请期待。

您可以向 Requires 标签添加更明确的 sub-fields,例如Requires(post): openssh-serverRequires(pre,post): openssh-server.

单个 RPM 事务不是 真正的 原子的,而是以这种方式处理的。如果没有此附加信息,它只会确保软件包已安装 在此事务结束时 ,大多数情况下是 "good enough"。

另一种选择是将所需的配置放入 %triggerin 节,我 相信 只有在安装了两个包后才会执行。