我正在使用 Ansible,我需要替换文件中的一行。该文件是 apache 的 logrotate 配置文件/etc/logrotate.d/apache2
。修改之前,该行内容为
/var/log/apache2/*.log {
我想替换为
/var/log/apache2/*.log /var/log/apache2/*/*.log {
我宁愿不重写整个文件,以免影响配置的内容。
我可以使用lineinfile
模块来做到这一点:
- name: Configure logrotate for Apache
lineinfile:
dest: /etc/logrotate.d/apache2
regexp: '^(/var/log/apache2/\*\.log) (?:/var/log/apache2/\*/\*\.log )?{$'
# The backrefs option is required to ensure the line won’t just be
# added, breaking the syntax of the file…
backrefs: yes
line: '\1 /var/log/apache2/*/*.log {'
不幸的是,如果配置文件中的正则表达式不匹配,则此任务成功(不执行任何操作)。我宁愿它失败。
我发现的解决方案是通过额外的任务检查配置:
- name: Check logrotate’s configuration for Apache
command: egrep '^/var/log/apache2/\*\.log /var/log/apache2/\*/\*\.log {$' /etc/logrotate.d/apache2
changed_when: no
这似乎有效,但我对正则表达式的重复感到不满意……
如果该线路不存在,那么是否有更好的方法来更改线路但失败?
请注意,我目前只能使用(相当古老的) Ansible 2.2,但我仍然对适用于新版本的解决方案感兴趣。
答案1
问:“修改前,该行内容为
/var/log/apache2/*.log {
我想替换为
/var/log/apache2/*.log /var/log/apache2/*/*.log {
答:下面的任务行输入文件
- lineinfile:
path: /etc/logrotate.d/apache2
regexp: '^(/var/log/apache2/\*\.log)\s+{$'
line: '\1 /var/log/apache2/*/*.log {'
backrefs: yes
问:“如果那条线路不存在,那么有没有更好的方法来改变这条线路而导致失败?”
答:以下任务失败,因为图案不在配置文件中
- fail:
msg: Pattern not in file
when: not lookup('file', my_conf).splitlines()|
select('match', pattern)|list
vars:
pattern: '^/var/log/apache2/\*\.log\s+{$'
my_conf: '/etc/logrotate.d/apache2'
- replace:
path: /etc/logrotate.d/apache2
regexp: '^(/var/log/apache2/\*\.log)\s+{$'
replace: '\1 /var/log/apache2/*/*.log {'