rpm%config(noreplace)覆盖%config

时间:2015-09-16 13:47:40

标签: linux rpm rpm-spec

在我的rpm中,我有一个完整的目录,我想用%config(noreplace)标记。使用%config中的语义,我希望在每次安装时使用rpm中的最新版本替换该目录中的文件。

使用此处的指南:http://www-uxsup.csx.cam.ac.uk/~jw35/docs/rpm_config.html,我尝试了以下内容:

%files
%config(noreplace) /my/saved/dir/*
%config /my/saved/dir/file1

%files
%config /my/saved/dir/file1
%config(noreplace) /my/saved/dir/*

希望特定的命令会覆盖glob,但它不起作用。是否有任何类似RPM的命令可以用来强制嵌套在%config(noreplace)目录下的文件上的%config行为?

2 个答案:

答案 0 :(得分:5)

自: http://ftp.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html

  

%config指令有限制,并且有限制   是%的配置文件后面只有一个文件名。这意味着   以下示例是唯一允许指定config的方法   文件:

%config /etc/foonly
     

请注意,在构建时安装文件的完整路径是必需的。

但是,您可以在%install部分中动态制作该列表:

%install
echo '%dir /etc' >> list.txt
echo '%config(noreplace) /etc/foo' >> list.txt
# use for-loop or any other shell scripting technique

%files -f list.txt

答案 1 :(得分:1)

假设包中的每个文件都列在 .spec 文件的%files 部分(列表)中完全一次。我打赌当你跑步rpmbuild时,输出中有以下行

warning: File listed twice: /my/saved/dir/file1

解决方案是列出配置文件(您希望始终覆盖)仅使用适当的指令,即%config(noreplace)。这是无论是通过通配符直接还是间接指定的。

msuchy的回答中提到的陈述

  

%config指令有限制,并且有限制   就是%config之后只能有一个文件名。

必须远离过去,因为早在2008年就有%config 指令中使用通配符的规范文件示例。

问题不在于使用通配符本身。问题是同一个文件被列出两次(一次直接,一次是间接使用通配符)和不同的%config 指令(一次使用普通%config < / em>和一次使用%config(noreplace))。您的测试 - 更改这两个声明的顺序 - 以及您观察到的结果表明 rpm 将这两个声明合并到一个%config(noreplace)中。这可以解释为什么声明的顺序无关紧要。但是,正如我上面所写的那样,假设每个文件只列出一次,这可能是我找不到任何关于某个文件被多次列出时应该发生什么的信息的原因。

请注意,%config(noreplace)指定的文件必须已更改 - 包中 - 已安装的版本与要安装的较新版本之间要写的 .rpmnew 文件 - 请参阅.rpmnew file not created on package upgrade?

请注意,安装较新版本的某些软件包不会被视为更新软件包 - 请参阅Unexpected RPM conflict on %config(noreplace) files

以下是那些想要尝试自己的人的规范文件。

mypackage的-old.spec

Summary: old version
Name: mypackage
Version: 1
Release: 1
License: BSD

%description
https://stackoverflow.com/questions/32610487/

%prep

%build

%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/foo
echo 'replace' > %{buildroot}/foo/replace
echo 'noreplace' > %{buildroot}/foo/noreplace

%clean
rm -rf %{buildroot}


%files
%defattr(-,root,root,-)
%config /foo/replace
%config(noreplace) /foo/*

mypackage的-new.spec

Summary: new version
Name: mypackage
Version: 2
Release: 1
License: BSD

%description
https://stackoverflow.com/questions/32610487/

%prep

%build

%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/foo
echo 'new replace' > %{buildroot}/foo/replace
echo 'new noreplace' > %{buildroot}/foo/noreplace

%clean
rm -rf %{buildroot}

%files
%defattr(-,root,root,-)
# declaration A    
%config /foo/replace    
# declaration B
%config(noreplace) /foo/*

无论我们在上面声明A和B的顺序是什么顺序,RPM版本4.14.0的结果都是相同的:

% rpmbuild -ba ./mypackge-old.spec
% rpmbuild -ba ./mypackge-new.spec
% sudo rpm -i ~/rpmbuild/RPMS/x86_64/mypackage-1-1.x86_64.rpm
% echo modified >> /foo/replace
% echo modified >> /foo/noreplace
% sudo rpm -U ~/rpmbuild/RPMS/x86_64/mypackage-2-1.x86_64.rpm
warning: /foo/noreplace created as /foo/noreplace.rpmnew
warning: /foo/replace created as /foo/replace.rpmnew