Usually, when applying package updates via yum update, rpm is 'intelligent' enough to respect my changes to configuration files under /etc.(It basically looks at the mtime, compares it and depending on the outcome replaces the file with the new version, or just puts the new version beside it.)But with one of the last yum/yum-cron updates on Centos 7, my custom yum-cron config files were replaced:/etc/yum/yum-cron.conf/etc/yum/yum-cron-hourly.confNow I am wondering why this happened exactly?I mean, the answer must be in the source package - but I can't find it there:$ rpm -qi yum-cron | grep srcSource 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.confLooking at the spec file, in the yum-cron section, the config directive even has noreplace specified.On the other hand, the ownership of the config files seems to be shared among the yum and the yum-cron binary packages:$ 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.confHow come?I mean, I only see the yum-cron config files mentioned in the cron specific files section of the spec file ...See also the CentOS issue and the RHEL issue on this.
Why does a yum package update replaces my yum-cron config files?
centos;rhel;yum;rpm
This is due to the following line in the main %files section of the yum.spec file:%(dirname %{compdir})Meaning that rpm first substitutes %{compdir} and then executes dirname with the result as argument in a shell. The output is then added to the file list.The compdir variable is defined like this:%define compdir %(pkg-config --variable=completionsdir bash-completion)%if %{compdir} == %define compdir /etc/bash_completion.d%endifAssuming that bash-completion is installed at build time (on the build system), pkg-config thus returns perhaps:/usr/share/bash-completion/completionsAnd thus addingdirname /usr/share/bash-completion/completions-> /usr/share/bash-completionto the file list is ok (and makes sense if the yum package also installs helpers, i.e. under /usr/share/bash-completion/helpers).The problematic case is when the bash-completion package is not installed at build time because then pkg-config returns the empty string, i.e.: compdir := /etc/bash_completion.d => dirname /etc/bash_completion.d -> /etcThus, the complete /etc directory from the package's buildroot is recursively added to the file list.Apparently, the box where the CentOS yum binary package was built didn't have the bash-completion package installed. In fact, RHEL (and thus CentOS) does not even provide a bash-completion package.This explains why the files/etc/yum/yum-cron.conf/etc/yum/yum-cron-hourly.confare owned by both the yum and the yum-cron package.(And are only correctly marked by the yum-cron package.)AddendumThe motivation for the conditionals is probably the idea to have one yum spec file for multiple rpm based distributions (e.g. different versions of Fedora, RHEL, ...). Consequent, the spec file also conditionally build-depends and bash-completions only on non-RHEL systems:%if ! 0%{?rhel}# we don't have this in rhel yet...BuildRequires: bash-completion%endifThe change that introduced dirname was discussed on the yum mailinglist:package also $(compdir)'s parent (not sure why, just in case)The introduction of the conditional logic was also discussed:Oh, and instead of hardcoding the completions dir, it'd be better to  get it from pkg-config --variable=completionsdir bash-completion.Spec FixOne fix is to move the dirname call into the right conditional branch, e.g.:--- 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?