使 RPM 规范文件中的 Requires 部分与操作系统相关

使 RPM 规范文件中的 Requires 部分与操作系统相关

情况

我有一个在安装后和卸载前阶段使用semanage(SELinux 策略管理工具)和(SELinux 上下文配置工具)的 RPM 。restorecon

不幸的是,在 RHEL 6/7 和 8 之间,包含这些工具的软件包已从 重命名policycoreutils-pythonpolicycoreutils-python-utils.

RHEL8 RPM 的工作规范文件包含:

Requires(post): policycoreutils-python-utils
Requires(preun): policycoreutils-python-utils

RHEL6/7 RPM 的工作规范文件包含:

Requires(post): policycoreutils-python
Requires(preun): policycoreutils-python

我试图实现的目标

可以与两个规范文件/两个 RPM 一起生活,每个操作系统类型一个,但我很懒,我想要一个服务于所有人的规范。

我尝试过的

我读到了有关操作系统条件的信息%{rhel},其中包含操作系统版本。下列应该工作,根据 RPM 手册:

%if %{rhel} < 8
Requires(post): policycoreutils-python
Requires(preun): policycoreutils-python
%endif 

%if %{rhel} == 8
Requires(post): policycoreutils-python-utils
Requires(preun): policycoreutils-python-utils
%endif

%{rhel}如果我检查目标系统上变量的值,我会得到我所期望的结果:

centos7-system» rpm --eval '%{rhel}'
7

centos8-system» rpm --eval '%{rhel}'
8

在 CentOS 6/7 实例上安装此 RPM 效果很好。但是,在 CentOS 8 实例上安装独立于操作系统的 RPM 后,我得到:

centos8-system» dnf install my-1.26-0.x86_64.rpm
<...>
Error:
 Problem: conflicting requests
  - nothing provides policycoreutils-python needed by my-1.26-0.x86_64

调试输出:

centos8-system» rpm -ivvvh my-1.26-0.x86_64.rpm 2>&1 | grep Requires
D:  Requires: /bin/bash                                     YES (db files)
D:  Requires: /bin/sh                                       YES (db files)
D:  Requires: /bin/sh                                       YES (cached)
D:  Requires: /bin/sh                                       YES (cached)
D:  Requires: /usr/bin/env                                  YES (db files)
D:  Requires: /usr/bin/perl                                 YES (db files)
D:  Requires: /usr/bin/php                                  YES (db files)
D:  Requires: nagios-plugins                                NO
D:  Requires: perl(Getopt::Long)                            YES (db provides)
D:  Requires: perl(strict)                                  YES (db provides)
D:  Requires: policycoreutils-python                        NO
D:  Requires: policycoreutils-python                        NO  (cached)
D:  Requires: policycoreutils-python                        NO
D:  Requires: rpmlib(CompressedFileNames) <= 3.0.4-1        YES (rpmlib provides)
D:  Requires: rpmlib(FileDigests) <= 4.6.0-1                YES (rpmlib provides)
D:  Requires: rpmlib(PayloadFilesHavePrefix) <= 4.0-1       YES (rpmlib provides)
D:  Requires: rpmlib(PayloadIsXz) <= 5.2-1                  YES (rpmlib provides)

似乎Requires使用的是 CentOS 6/7 场景的 ,而不是 CentOS 8 场景中的。

我在这里没有看到什么?我可以做些什么来调试这个吗?

相关内容和来源

答案1

您可以省略条件并依赖于 semanage 可执行文件而不是policycoreutils-python 包:

Requires(post): %{_sbindir}/semanage
Requires(post): %{_sbindir}/restorecon

参见 Fedora 的dokuwiki.spec举个例子。取决于软件包的示例是bdii规范

答案2

SPEC 文件中的条件正在评估期间建造时间。因此,当您的 SPEC 文件包含:

%if %{rhel} < 8
Requires(post): policycoreutils-python
%endif 

%if %{rhel} == 8
Requires(post): policycoreutils-python-utils
%endif

然后你在 RHEL 7 上构建你的包,然后它就会有

Requires(post): policycoreutils-python

即使您在 RHEL 8 上安装软件包,也会使用此 Requires。软件包构建后不会重新评估。

如果您只想拥有一个二进制包,那么您需要文件库,正如 Andreas 指出的那样。企业解决方案是使用

Release: 1%{?dist}
...
%if %{rhel} < 8
Requires(post): policycoreutils-python
Requires(preun): policycoreutils-python
%endif 

%if %{rhel} == 8
Requires(post): policycoreutils-python-utils
Requires(preun): policycoreutils-python-utils
%endif

并使用以下方法为不同平台构建它:

mock -r epel-7-x86_64 my.src.rpm
mock -r epel-8-x86_64 my.src.rpm

第一个命令产生my-1.0-1.el7并要求policycoreutils-python,而第二个命令产生my-1.0-1.el8并要求policycoreutils-python-utils

作为旁注,条件应写为:

%if 0%{?rhel} < 8

以防止未定义宏时出现语法错误。

相关内容