我正在尝试打包由许多包组成的产品。
我成功地编写了所有规范文件、包之间的依赖关系等等。它们都已安装并且工作正常。
我没有成功做的一件事是运行预申请测试:在某些情况下,我希望根本不安装软件包,并且用户收到错误,向他解释他需要首先修复什么,在运行软件包安装之前。
例如:我想验证用户是否在运行级别 3 下运行,如果没有,则中止整个安装,并要求用户在“最小”配置文件中重新安装 CentOS - 因为我不需要所有额外的软件包与“桌面”一起提供。 (这只是一个例子,我有一些这样的测试要执行)。
我处理这个问题的方法是这样的:
我创建了一种“元包”,它的名称出现在所有其他包的“Requires:”指令中,因此它将首先由 YUM 安装,并且在该包规范文件的 部分中,%pre
我执行了我想要执行的各种测试,在适用时输出测试错误,然后“ exit 1
”。
我选择这种方法的原因是:“如果每个包都依赖于这个包,并且这个包无法安装,那么一旦包管理器想要安装依赖于安装失败的包的包,事务就必须失败。 ..毕竟,依赖性尚未得到满足”。例如,在 Gentoo 中,如果某个软件包由于某种原因安装失败,emerge 会完全停止——即使不是因为依赖问题;并且有一个特殊的标志告诉 emerge 继续,尽管其中一个包返回了错误。
问题是,当测试失败时,包确实失败了(RPM 特别说它返回了代码 1),但是...YUM 似乎并不真正关心这种情况的发生 - 并且只是继续安装其他所有内容,包括以下包依赖于未安装的软件包(!)。最后,它只是报告所有软件包都已成功安装,除了故意失败的软件包......
我猜测其原因是依赖项检查发生在事务开始之前,并且实际上,依赖项是从 YUM 可以使用的各个存储库中得到满足的。尽管如此,如果依赖项最终失败,依赖包的安装将继续,这对我来说没有任何意义。
我的逻辑有问题吗?我怀疑这是一个错误,因为现在已经有人遇到过它了(如果重要的话,这是在 CentOS 6.3 上......) - 但我所有的 Google-foo 都没有产生任何结果。我什至没有发现有人问同样的问题......也许我使用了错误的关键字?
我的做法是错误的吗?任何其他想法(适合 RPM 规范或其他 YUM 存储库魔法,甚至在 YUM .repo 文件中... - 但全部包含在 YUM 基础设施内,无需在“yum install”之前运行外部脚本) - 将不胜感激!
答案1
在该包规范文件的 %pre 部分中,我做了我想要执行的各种测试,在适用时输出测试错误,然后“退出 1”。
这是行不通的,当 %pre 脚本失败时,rpm 不会停止/展开事务。 rpm 在很多方面都无法处理 ACID 事务,这就是其中之一。您需要添加冲突以在 depsolve 阶段停止事务。
答案2
基本上,您不需要一个神奇的标志来 yum,而是需要某种形式的 %pretrans 脚本来检查您的要求,对吗? %pretrans 从 rpm 4.4 开始可用。查看http://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Syntax或者可能http://wiki.networksecuritytoolkit.org/nstwiki/index.php/RPM_Quick_Reference#Secret_.25pretrans_and_.25posttrans_RPM_Scriptlets
有关更多信息,请参阅以下位置的讨论和缺点:https://fedorahosted.org/fpc/ticket/22
因此,创建一个 %pretrans scriptlet,将所有测试都堆在那里(运行级别、主机名)以及其他什么,以及何时总计 $?等于 0 则事务将开始,否则事务将失败。
尽管这种方法听起来绝对是一个逻辑缺陷。
对于你的问题,为什么 yum 不会因第一个包失败而停止:因为你基本上告诉它安装,比如说十几个包。其中一个失败了,但其他的不依赖于那个(否则你最终会得到循环依赖,这也可能很棘手),所以其他的将被安装。这是正常行为。您可以将所有依赖包更改为Requires(pre): yourmetapackagehere >= some.version
要更改所有依赖项的安装顺序,可以使用“上下文标记的依赖项”(ordered dependency)检查,例如这个资源