通常,当通过应用程序包更新时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 配置文件......
答案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
均归yum
和yum-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