使用 Ansible 替换文件中的某一行,同时确保该行存在

使用 Ansible 替换文件中的某一行,同时确保该行存在

我正在使用 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 {'

相关内容