我有一个rpm的问题,让我撕掉我的头发 .
我们已经创建了多个用于部署到内部服务器上的软件包 - 其中一些是在不同(但相关)系统中使用的基础软件包(共享库),其中一些是特定于应用程序的库 .
为简化起见,包和要求如下:
SharedLib-ver.x
ApplicationLib-ver.x [Requires SharedLib-ver.x]
UserInterface-ver.x [Requires ApplicationLib-ver.x]
要安装,sysadmin一直在使用atomic命令
rpm -Uvh SharedLib.rpm ApplicationLib.rpm UserInterface.rpm
只要所有软件包都正确安装,它就可以正常工作,但如果任何软件包安装失败,它都无法正常工作 .
在测试条件下,我们已经验证了rpm正确 Build 了依赖关系,并且正在尝试以正确的顺序安装/升级软件包,无论它们包含在原子rpm -Uvh命令中的顺序如何 .
当其中一个软件包在%pre阶段失败时(即%pre具有非零退出状态),会出现特定问题
如果使用如上所示的原子安装/升级命令进行安装,则会正确报告
error: %pre(SharedLib-ver.x.noarch) scriptlet failed, exit status 1
but ,它继续升级/安装依赖包,无论如何 .
但是,如果包顺序升级/安装,即:
rpm -Uvh SharedLib.rpm;
rpm -Uvh ApplicationLib.rpm;
rpm -Uvh UserInterface.rpm;
它无法使用与上面相同的错误安装SharedLib,然后正确拒绝安装剩余的包,因为尚未满足依赖项 . 这是我期望的行为 .
对于它的 Value ,如果%pretrans scriptlet以非零退出状态终止,也会发生同样的事情(根据定义,我认为pretrans应该在rpm事务开始之前完成!) . 我已经看到它建议显式依赖/版本检查可以包含在%pretrans部分中,但这对我来说完全是错误的,并且似乎首先打败了使用包管理器的全部原因!
rpm版本是4.8.0,我们已经在CentOs和RedHat服务器上验证了这种行为 .
首先,实际上是否可以在单个原子命令中安装多个包,如图所示,同时尊重这些包提供的依赖关系?
如果是这样,我怎么能做到这一点?
我确定原因和/或解决方案是微不足道的,但是我已经围绕这个问题进行了圆周讨论,似乎无法找到解决方案 .
编辑
继Matt Schuchard的评论(谢谢)之后,我尝试了'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 <packages>'之后,rpm -qa显示安装了ApplicationLib和UserInterface,但是没有安装SharedLib,这是完全相同的问题我在用rpm直接安装时有!
只是绝对100%确定,我已经卸载了所有内容,然后尝试(反过来)rpm安装,rpm升级和yum安装ApplicationLib-ver.x.noarch,并且在每种情况下,它都会失败,因为SharedLib不存在 .
编辑(2)
谢谢,杰夫,您的额外回复 .
我100%试图避免%pre测试中的任何“花哨”脚本 - 只是感觉从根本上感觉它试图强制行为(如果一切设置正确),应该通过rpm本质上处理 .
我的第一种方法是(完全按照你的建议) - 添加窄(特定于版本)的依赖项
即在ApplicationLib中
Requires: SharedLib = %{version}
在UserInterface中
Requires: ApplicationLib = %{version}
在所有情况下,%的扩展都是相同的
如果软件包是按顺序安装的,那么这种方法很有效,但是让我感到困惑的是为什么rpm / yum会跳过SharedLib,但是如果所有三个软件包都安装在一个命令中,它仍会继续安装依赖它的软件包 .
如果我解释这些软件包构成一个后端Web应用程序并更新某些部分而不是其他风险,那么可能会使事情更加清晰,从而导致用户体验不尽如人意,最糟糕的是数据损坏 . 为了最大限度地降低此风险,SharedLib完成了许多预安装测试,以确保系统安全并准备接受更新(例如,Web服务器处于安全状态以继续安装 - 存在并停止)和如果可以安全继续,其他内务处理任务的数量(例如,停止也是应用程序的一部分的自定义服务,版本化日志轮换等) .
如果服务器(例如)存在但正在运行和提供页面,则继续升级的任何步骤都是不安全的,因此sharedLib rpm退出并向sysadmin解释了安全继续所需的内容 . 显然,如果安装了依赖库而不管基本依赖性中的失败,这是不合需要的情况 .
好的,所以这几乎是针对仓促手指的保险政策(安装说明已经明确,因为服务器不能运行),但这似乎不是一件不合理的事情(YMMV!)
当然,我可以强制要求rpms没有安装在单行yum / rpm命令中,但这只是感觉就像rpm应该能够以可预测的方式处理,只要我能正确设置所有内容,无论如何都不保证会遵守任何此类指示 .
1 回答
据推测,您希望使用rpm的3个软件包的全有或全无原子升级行为,并尝试使用脚本化测试强制执行该行为 .
由于上下文,使用%pretrans的脚本永远不会成功:当运行%pretrans脚本时,当前事务集中没有任何内容安装;因此,您无法编写测试成功安装的脚本 .
您似乎期望先决条件中的%pre故障将导致依赖包也失败 . 这不是%pre的工作原理:%pre的失败将导致跳过该包(带有警告) . 这实际上就是你所看到的rpm / yum,主要区别在于yum似乎阻止来自rpm的警告消息 .
(旁白)如果先决条件无法安装,您可能可以添加前提条件的显式%预测试以跳过依赖包的安装,但仍然不是全有或全无的原子行为,因为rpm不会撤消已经成功的安装执行 .
同时脚本%预测试不是正确的方法 . 您需要关注应用程序的故障模式 . 据推测,当您在正在运行的应用程序下升级库时,您担心UI失败 . 首先,正在运行的应用程序具有共享库的引用计数,并且即使通过包升级删除库也将继续运行 .
例如,如果您的应用程序调用在升级之后/期间以某种方式不兼容的可执行文件,则需要在应用程序中处理,而不是在打包中处理 .
否则,添加narrow(即使用特定版本和发行版)依赖项将确保升级事务中包含全部或全部软件包 . RPM(缺少特殊的病态,如断电和/或无磁盘空间,或有缺陷的包装,或有缺陷的rpm)将成功安装 .
那你担心什么类型的失败?可能有一个解决方案......