ansiblecentos7ansible-module

using lineinfile to insert line but not working as expected


I am using lineinfile to insert line in syslog file. Here is my syslog:

/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
    missingok
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

I would like to add compress and delaycompress after missingok. Here is my code:

- name: "Adding compress line in /etc/logrotate.d/syslog"
  lineinfile:
    path: /etc/logrotate.d/syslog
    insertafter: "^missingok"
    line: "    compress"
    firstmatch: yes
    state: present

- name: "Adding delaycompress line in /etc/logrotate.d/syslog"
  lineinfile:
    path: /etc/logrotate.d/syslog
    insertbefore: "^sharedscripts"
    line: "    delaycompress"
    firstmatch: yes
    state: present

But its adding both at the end of the file(at last lines).
Note: I have added 4 spaces before compress and delaycompress.


Solution

  • This is happening because the caret ^, in a regex, matches the start of a string without consuming any characters.

    And because you do have spaces before missingok and sharedscripts, your insertafter and insertbefore regex are matching nothing.

    To fix this, you can allow spaces and spaces only at the beginning of the line with the help of \s that matches any space, tab or newline character and of the star * that matches zero or more consecutive characters.

    So the correct regex would be

    And the fix for your tasks would be:

    - name: "Adding compress line in /etc/logrotate.d/syslog"
      lineinfile:
        path: /etc/logrotate.d/syslog
        insertafter: "^\\s*missingok"
        line: "    compress"
        firstmatch: yes
        state: present
    
    - name: "Adding delaycompress line in /etc/logrotate.d/syslog"
      lineinfile:
        path: /etc/logrotate.d/syslog
        insertbefore: "^\\s*sharedscripts"
        line: "    delaycompress"
        firstmatch: yes
        state: present
    

    Note that, because Ansible is a Python application, backslashes \ have a special meaning and have to be escaped.