为什么 yum 软件包更新会替换我的 yum-cron 配置文件?

为什么 yum 软件包更新会替换我的 yum-cron 配置文件?

通常,当通过应用程序包更新时yum update,rpm 是'聪明的'足以尊重我对/etc.

(它基本上查看 mtime,进行比较,并根据结果用新版本替换该文件,或者只是将新版本放在它旁边。)

但随着 Centos 7 上最后一次 yum/yum-cron 更新之一,我的自定义 yum-cron 配置文件被替换了:

/etc/yum/yum-cron.conf
/etc/yum/yum-cron-hourly.conf

现在我想知道为什么会发生这种情况?

我的意思是,答案必须在源代码包中 - 但我在那里找不到它:

$ rpm -qi yum-cron | grep src
Source RPM  : yum-3.4.3-132.el7.centos.0.1.src.rpm
$ yumdownloader --source yum-3.4.3-132.el7.centos.0.1
$ grep '%.*yum-cron.*\.conf' yum.spec
%config(noreplace) %{_sysconfdir}/yum/yum-cron.conf
%config(noreplace) %{_sysconfdir}/yum/yum-cron-hourly.conf

查看规范文件,在 yum-cron 部分中,配置指令甚至有noreplace指定的。

另一方面,配置文件的所有权似乎在二进制包之间yum共享yum-cron

$ rpm -ql yum-cron | grep 'yum-cron.*\.conf'
/etc/yum/yum-cron-hourly.conf
/etc/yum/yum-cron.conf
$ rpm -ql yum | grep 'yum-cron.*\.conf' 
/etc/yum/yum-cron-hourly.conf
/etc/yum/yum-cron.conf

怎么会?

我的意思是,我只看到规范文件的 cron 特定文件部分中提到的 yum-cron 配置文件......

另请参阅CentOS问题RHEL问题关于这一点。

答案1

这是 Red Hat 创建软件包的方式存在的问题 - 该yum-cron.conf文件应该被标记为配置文件(与您的输出指示的情况相反),但事实并非如此(查询已安装软件包的配置文件不会列出该文件yum-cron.conf)。实际的答案是让 RH 修复它,可能更有用的答案是chattr +i。另请参阅:https://serverfault.com/questions/744531/secure-yum-cron-conf-configuration-and-prevent-them-from-getting-auto-updated/744535#744535

答案2

%files这是由于文件主要部分中的以下行所致yum.spec

%(dirname %{compdir})

这意味着 rpm 首先进行替换%{compdir},然后将dirname结果作为 shell 中的参数执行。然后输出将添加到文件列表中。

compdir 变量定义如下:

%define compdir %(pkg-config --variable=completionsdir bash-completion)
%if "%{compdir}" == ""
%define compdir "/etc/bash_completion.d"
%endif

假设bash-completion在构建时安装(在构建系统上),pkg-config因此可能返回:

/usr/share/bash-completion/completions

从而添加

dirname /usr/share/bash-completion/completions
-> /usr/share/bash-completion

到文件列表就可以了(如果 yum 包也安装了帮助程序,即在 下,则有意义/usr/share/bash-completion/helpers)。

有问题的情况是当bash-completion构建时未安装包时,因为然后pkg-config返回空字符串,即:

 compdir := /etc/bash_completion.d
 => dirname /etc/bash_completion.d
 -> /etc

/etc因此,包的 buildroot 中的完整目录会递归地添加到文件列表中。

显然,构建 CentOS yum 二进制包的盒子没有bash-completion安装该包。事实上,RHEL(以及 CentOS)甚至不提供软件包bash-completion

这解释了为什么这些文件

/etc/yum/yum-cron.conf
/etc/yum/yum-cron-hourly.conf

均归yumyum-cron包所有。

(并且仅在包装上正确标记yum-cron。)

附录

条件语句的动机可能是为多个基于 rpm 的发行版(例如不同版本的 Fedora、RHEL 等)提供一个 yum 规范文件。因此,spec 文件也有条件地依赖于构建,并且bash-completions仅在非 RHEL 系统上:

%if ! 0%{?rhel}
# we don't have this in rhel yet...
BuildRequires: bash-completion
%endif

引入 dirname 的更改是在 yum 邮件列表上讨论:

包也是 $(compdir) 的父级(不知道为什么,以防万一)

的介绍还讨论了条件逻辑:

哦,与其硬编码完成目录,最好从“pkg-config --variable=completionsdir bash-completion”获取它。

规格修复

一种解决方法是将dirname调用移至正确的条件分支,例如:

--- a/SPECS/yum.spec
+++ b/SPECS/yum.spec
@@ -28,7 +28,7 @@ BuildRequires: bash-completion

 # disable broken /usr/lib/rpm/brp-python-bytecompile
 %define __os_install_post %{nil}
-%define compdir %(pkg-config --variable=completionsdir bash-completion)
+%define compdir %(pkg-config --variable=completionsdir bash-completion | xargs -r dirname)
 %if "%{compdir}" == ""
 %define compdir "/etc/bash_completion.d"
 %endif
@@ -451,7 +451,7 @@ exit 0
 %dir %{_sysconfdir}/yum/fssnap.d
 %dir %{_sysconfdir}/yum/vars
 %config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
-%(dirname %{compdir})
+%{compdir}
 %dir %{_datadir}/yum-cli
 %{_datadir}/yum-cli/*
 %exclude %{_datadir}/yum-cli/completion-helper.py?

答案3

感谢您的详细解释马克斯施莱普齐格,但您建议的修复不正确。这会导致 comdir/usr/share/bash-completion在安装 bash-completion 时被设置。那里的文件未加载,它们必须位于/usr/share/bash-completion/completions.这将破坏始终用作完成文件的安装路径的能力%{compdir},而这正是宏的全部意义。

解决这个问题最安全的方法是明确:

%if 0%{?fedora} >= 19 || 0%{?rhel} >= 7
%global compdir %{_datadir}/bash-completion/completions
%else
%global compdir %{_sysconfdir}/bash_completion.d
%endif

然后在 %files 部分:

%if 0%{?fedora} >= 19 || 0%{?rhel} >= 7
%(dirname %{compdir})
%else
%{compdir}
%endif

相关内容