【问题标题】:rpm: dependencies not failing on simultaneous installation/upgrade of multiple packagesrpm:在同时安装/升级多个软件包时依赖项不会失败
【发布时间】:2016-06-09 10:00:07
【问题描述】:

我遇到了 rpm 问题,导致我的头发掉光了。

我们创建了多个包以部署到内部服务器上 - 其中一些是跨不同(但相关)系统使用的基本包(共享库),其中一些是特定于应用程序的库。

为简化起见,包和要求如下:

SharedLib-ver.x
ApplicationLib-ver.x  [Requires SharedLib-ver.x]
UserInterface-ver.x   [Requires ApplicationLib-ver.x]

要安装,系统管理员一直在使用 atomic 命令

rpm -Uvh SharedLib.rpm ApplicationLib.rpm UserInterface.rpm

只要所有软件包都正确安装,它就可以正常工作,但如果任何软件包安装失败,它就不会像我预期的那样工作。

我们已经在测试条件下验证了 rpm 正确地建立了依赖关系,并尝试以正确的顺序安装/升级软件包,无论它们包含在 atomic rpm -Uvh 命令中的顺序如何。

当其中一个包在 %pre 阶段失败(即 %pre 具有非零退出状态)时,就会出现特定问题

如果使用原子安装/升级命令如上所示安装,它会正确报告

error: %pre(SharedLib-ver.x.noarch) scriptlet failed, exit status 1

但是,它会继续升级/安装依赖包。

但是,如果软件包是按顺序升级/安装的,即:

rpm -Uvh SharedLib.rpm; 
rpm -Uvh ApplicationLib.rpm; 
rpm -Uvh UserInterface.rpm;

它无法安装 SharedLib 并出现与上述相同的错误,然后由于未满足依赖关系而正确拒绝安装剩余的软件包。这是我所期望的行为。

不管怎样,如果 %pretrans 脚本以非零退出状态终止,同样的事情也会发生(根据定义,我认为 pretrans 应该在 rpm 事务之前完成开始!)。我已经看到它建议可以在 %pretrans 部分中包含显式依赖/版本检查,但这对我来说完全错误,并且似乎首先破坏了使用包管理器的全部原因!

rpm 版本是 4.8.0,我们已经在 CentO 和 RedHat 服务器上验证了此行为。

首先,实际上是否可以在一个原子命令中安装多个包,如图所示,同时尊重这些包提供的依赖关系?

如果是这样,我怎样才能做到这一点?

我确信原因和/或解决方案是微不足道的,但我一直在这个问题上兜圈子,似乎找不到解决方案。

编辑

除了 Matt Schuchard 的 cmets(谢谢)我已经尝试过“yum install”方法。

删除脚本输出和其他无关信息,运行:

yum install ApplicationLib-ver.x.noarch.rpm UserInterface-ver.x.noarch.rpm SharedLib-ver.x.noarch.rpm

给了

Examining UserInterface-ver.x.noarch.rpm: UserInterface-ver.x.noarch
Marking UserInterface-ver.x.noarch.rpm to be installed
Examining SharedLib-ver.x.noarch.rpm: SharedLib-ver.x.noarch
Marking SharedLib-ver.x.noarch.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package UserInterface.noarch 0:ver.x will be installed
---> Package ApplicationLib.noarch 0:ver.x will be installed
---> Package SharedLib.noarch 0:ver.x will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================================================================================================
 Package                                  Arch                    Version                     Repository                                                Size
=============================================================================================================================================================
Installing:
 UserInterface                            noarch                     x                     /UserInterface-ver.x.noarch                                 203 k
 ApplicationLib                           noarch                     x                     /ApplicationLib-ver.x.noarch                                2.0 M
 SharedLib                                noarch                     x                     /SharedLib-ver.x.noarch                                      19 M

Transaction Summary
=============================================================================================================================================================
Install       3 Package(s)

Total size: 21 M
Installed size: 21 M
Is this ok [y/N]: y
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction

error: %pretrans(SharedLib-ver.x.noarch) scriptlet failed, exit status 1
Error in PRETRANS scriptlet in rpm package SharedLib-ver.x.noarch

  Verifying  : ApplicationLib-ver.x.noarch                                                                                                   1/3
  Verifying  : UserInterface-ver.x.noarch                                                                                                    2/3
  Verifying  : SharedLib-ver.x.noarch                                                                                                        3/3

Installed:
  UserInterface.noarch 0:ver.x                                        ApplicationLib.noarch 0:ver.x

Failed:
  SharedLib.noarch 0:ver.x

Complete!

所以 yum 获得了基本依赖项和正确的安装顺序(大概从 rpm 无论如何),但是在执行 'yum install ' 之后,rpm -qa 显示 ApplicationLib 和 UserInterface 已安装,但 SharedLib 未安装,这是确切的直接用 rpm 安装时遇到同样的问题!

为了绝对 100% 确定,我已经卸载了所有内容,然后尝试(依次)进行 rpm 安装、rpm 升级和 yum 安装 ApplicationLib-ver.x.noarch 以及 每个在这种情况下,它会像预期的那样失败,因为 SharedLib 不存在。

编辑(2)

感谢 Jeff,您的补充回复。

我 100% 试图在 %pre 测试中避免任何“花哨”的脚本 - 从根本上感觉就像是在试图强制一种行为(如果一切设置正确),应该由 rpm 本质上处理.

我的第一种方法是(完全按照您的建议) - 添加狭窄的(特定于版本的)依赖项

即在应用程序库中

Requires: SharedLib = %{version}

在用户界面中,

Requires: ApplicationLib = %{version}

%{version} 的扩展在所有情况下都相同

如果软件包是按顺序安装的,这非常有效,但仍然让我感到困惑的是,为什么 rpm/yum 会跳过 SharedLib,但如果所有三个软件包都安装在一个命令中,它仍然会继续安装依赖它的软件包。

如果我解释说这些包构成一个后端 Web 应用程序并更新某些部分而不是其他部分,充其量会导致用户体验不满意,最坏的情况是数据损坏,这可能会让事情变得更清楚。为了最大限度地降低这种风险,SharedLib 完成了一些预安装测试,以确保系统安全并准备好接受更新(例如,网络服务器处于安全状态以继续安装 - 存在和停止)和如果可以安全地继续,其他内务管理任务的数量(例如,停止也是应用程序一部分的自定义服务,版本化日志轮换等)。

如果服务器(例如)存在但正在运行并提供页面,则继续升级的任何步骤都是不安全的,因此 sharedLib rpm 退出并向系统管理员解释安全继续所需的内容。显然,如果在安装依赖库时不考虑基本依赖项中的故障,这是不希望出现的情况。

好的,所以这几乎是针对草率手指的保险单(安装说明已经明确指出服务器不能运行),但这似乎不是不合理的事情(YMMV!)

当然,我可以强制要求不在单行 yum/rpm 命令中安装 rpm,但这感觉就像 rpm 应该能够以可预测的方式处理的事情,前提是我正确设置了所有内容,除此之外,不保证无论如何都会遵守任何此类指示。

【问题讨论】:

  • 如果您使用操作系统包管理器而不是rpm安装,则不会发生这种情况。
  • @Matt-schuchard 也许我在这里遗漏了一些东西 - 我正在尝试将它安装在 RedHat 服务器上(使用 CentOs 作为测试环境)并且印象中 rpm is RedHat 包管理器?无论如何,这是(在一定程度上)顺便说一句——规范要求包是通过 rpm 分发的。它在按顺序安装时按预期工作,但如果在单个事务中尝试则不会(与 %pretrans 脚本无关)
  • 如果你使用 dnf/zypper/yum 就可以了。请注意,这与其说是一种解决方案,不如说是一种变通方法,但同时通常不鼓励使用 rpm 而不是 OS 包管理器进行安装。
  • 所以,如果我理解这一点,你是在建议我继续创建和分发包作为 rpms 正常,但告诉系统管理员使用 yum 安装它们,而不是使用本机 rpm 安装/升级路线?好的,值得一试 :-) 但是,出于好奇是否有可以解决我原来的问题,或者是 rpm 的一个已知缺点(如果是,这是一个非常大的缺点,如果你问我!)
  • 所以我才意识到这是一个%preinstall 错误。在整个软件包的安装过程中,这可能不会被视为致命的安装错误(注意它在验证期间发生),这可能是这里的问题。

标签: rpm


【解决方案1】:

大概您希望 3 个带有 rpm 的软件包的原子升级行为全有或全无,并试图通过脚本测试来强制执行。

由于上下文,使用 %pretrans 的脚本永远不会成功:运行 %pretrans 脚本时,当前事务集中没有安装任何内容;因此,您无法编写测试成功安装的脚本。

您似乎期望先决条件中的 %pre 失败会导致依赖包也失败。这不是 %pre 的工作方式: %pre 的失败将导致该包被跳过(带有警告)。这实际上是您在使用 rpm/yum 时看到的,主要区别在于 yum 似乎阻止了来自 rpm 的警告消息。

(旁白) 如果先决条件安装失败,您可能可以添加先决条件的显式 %pre 测试以跳过依赖包的安装,但这仍然不是全有或全无的原子行为,因为 rpm 不会撤消成功的安装 已经执行了。

同时编写 %pre 测试脚本不是正确的方法。您需要关注应用程序的故障模式。据推测,当在运行的应用程序下升级库时,您会担心 UI 故障。首先,正在运行的应用程序对共享库有一个引用计数,并且即使库被软件包升级删除,它也会继续运行。

例如,如果您的应用程序在升级之后/升级期间调用了某种不兼容的可执行文件,则需要在应用程序中处理,而不是在打包中。

否则,添加狭窄的(即使用特定版本和发行版)依赖项将确保升级事务中包含全部或全部包。 RPM(没有异常情况,例如断电和/或没有磁盘空间,或有错误的包装,或有错误的 rpm)将成功安装。

那么您担心哪种类型的失败?可能有解决方案...

【讨论】:

  • 感谢您的回复,杰夫。我在原始问题中添加了一些更具体的用例信息(EDIT (2)),希望能更清楚地说明我想要实现的目标以及原因。
  • 好的。因此,您似乎在 SharedLib 中有一个复杂的预安装测试,有时需要系统管理员的手动干预。从重新启动中拆分分发(即安装)将允许完全自动化安装。基本上,将一个版本放在用于避免所有内容替换的目录上,并使用最后一个已知的良好内容重新启动以供运行。否则,您将需要构建预安装脚本,以便脚本自动修复并以某种方式避免人工干预。
  • 顺便说一句,有一个由 rpm --verify 运行的 %verifyscript 脚本可能会被填充以运行预安装脚本。这将允许手动指令,如“运行 rpm --verify SharedLib 并在升级应用程序之前修复所有问题。”
  • 太棒了。谢谢你。我会认真听取这些建议,看看我的进展如何!
猜你喜欢
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多