ansible syntax for lineinfile search and replace - syntax

My current etc/group wheel is setup as the following
wheel:x:10:admin,sshgroup,domaingroup
I need it be
wheel:x:10:admin4,sshlocal,domainusers,domainadmins
- name: add a string to the new file
lineinfile:
dest=/etc/group
backrefs=true
regexp='wheel:x:10:'
line='wheel:x:10:admin4,sshlocal,domainusers,domainadmins'
state = present
error:
The offending line appears to be:
line='wheel:x:10:admin4,sshlocal,domainusers,domainadmins'
state = present
^ here
I tried both with and without escaping : and commmas but to no avail. Can you please suggest. Im using ansible 2.2.1.0

Nevermind guys, playbook ran this time. I think last line where state = present is listed, i looked like used tab spaces instead of spaces for yaml. After I deleted that line and readded it with spaces, it works now.
cat /etc/group | grep wheel
wheel:x:10:admin4,sshlocal,domainusers,domainadmins
Apparently, single quote is good enough to escape: characters in YAML - which is good.

Related

before and after regex in replace block - caret isn't working as expected

Very difficult to understand ansible behavior. I'm trying to edit my /etc/postfix/master.cf file to turn on the submission block.
I copied the file to /tmp as I'm working on it, so my simple Ansible playbook should be:
- name: Edit the master.cf file
replace:
path: /tmp/master.cf
after: '^#tlsproxy'
before: '^#smtps'
regexp: '^#(.*)$'
replace: '\1'
But this doesn't work. It does work if I make one change, which is taking out the caret ^ in the before and after fields. This makes ... no sense to me at all. What makes even less sense, if I use:
after: '^#'
amazingly, it will do what I expect and uncomment all the lines after the first commented line.
But:
after: '^#t'
suddenly stops matching anything. I've read the Python page on regex and yet I'm baffled by this.
Any ideas? The playbook will work fine without the carets but I want to do this really correctly and match exactly what I want to match.
Thanks!
Ansible's replace module: uses DOTALL, which means the . special character can match newlines.
When you specify after: '^#tlsproxy', that caret is really saying: 'from the beginning of the search string, immediately followed by #tlsproxy', where the caret effectively means from the beginning of the file.
Ansible tries to match this:
"Pattern for before/after params did not match the given file: ^#tlsproxy(?P<subsection>.*?)^#smtps"
With re.DOTALL, if you want to match the patterns from the beginning of a line, use a newline character instead:
- name: Edit the master.cf file
replace:
path: master.cf
after: '\n#tlsproxy'
before: '\n#smtps'
regexp: '^#(.*)$'
replace: '\1'

Remove last three lines from file using ansible

I want to remove last three lines of file using ansible. I tried using lineinfile but it removed all the lines from file. I have posted below my file and ansible-playbook. I want to remove nfs_config, nfs_share and mount_path using lines using ansible.Thanks in advance.
file.txt
[images]
[tickets]
[unix sockets]
[nfs_config]
nfs_share=
mount_path=
Ansible-playbook
- name: Remove mount path from daemon.conf for clean-daemon
linefile:
path: /etc/ovirt-imageio-daemon/daemon.conf
regexp: "[nfs_config]"
state: absent
Use ini_file. The task below will remove the nfs_config section from the configuration file
- ini_file:
path: /etc/ovirt-imageio-daemon/daemon.conf
section: nfs_config
state: absent
regexp: "[nfs_config]" is not doing what you want, you need to use "[nfs_config]", otherwise you are matching any character that is between the []. This is why it's removing multiple lines.
https://docs.python.org/2/library/re.html
Also, just make 3 lineinfile command to match nfs_config, nfs_share and mount_path
You could use onee lineinifile with a complex regex to match them all, but it will be easier to read/maintain with 3 that are clear.

lineinfile query in ansible to replace or delete a string

While trying to install apache via ansible I am getting the error of libToolt hence my apr-util is not getting configured. I am trying to replace $RM "cfgfile" with $RM -f "cfgfile" in configure by using regexp it is either getting copied at the last or not working.
- name: Replace file
path: file path
regexp: '$RM -f "cfgfile"'
But the value that is going when I am trying to run my YAML file is
$RM\\\"$cfgfile\"
You must escape the $ in your regexp since that character is meaningful to regexp; or, skip the silliness and just use line: instead of regexp: since your text does not contain any variable parts (which is the circumstances under which one would use a regex)

Ansible lineinfile adding ^M to end of lines?

I am using ansible's lineinfile to update a file.
Once I've updated the file - which works - the file has ^M chars at the end of every line.
This behaviour is undesirable - how do I turn it off? It seems counter intuitive that I would then need to dos2unix in order to rectify?
- name: Update database.php - username
lineinfile:
dest: /var/www/html/database.php
regexp: '^\$username.*$'
line: "$username = '{{ mariadb_rc_user }}';"
backrefs: yes
edit note
Template and copy are possible but difficult to use in this situation for reasons I wont go into, but suffice to say: I'd use them if it made sense.
I found the answer and it was the opposite of what I expected. Neither lineinfile nor replace (see the duplicate link for a suggested solution) were the issue. In fact, they were doing their respective jobs - and ending lines with a line feed.
The problem arises because before that the file only has CLRF terminators, which are invisible when they exist exclusively.
When an LF is introduced, the CRLF (^M) is printed in vim to distinguish that there are now two types of line terminations.

Using ansible lineinefile with colon in line

I am trying to make sure that a particular line is commented out in a source file.
The line is like this:
CFUNCTYPE(c_int)(lambda: None)
If it exists, I want to comment it out:
# CFUNCTYPE(c_int)(lambda: None)
If it doesn't exist, just ignore it.
If it exists and is already commented out, do nothing.
This is the playbook I wrote, but it doesn't work.
tasks:
- name: fix ctypes file
lineinfile: dest='/usr/local/lib/python2.7/ctypes/__init__.py' regexp="^#?CFUNCTYPE(c_int)(lambda: None)" line='# CFUNCTYPE(c_int)(lambda: None)'
The error says:
This one looks easy to fix. There seems to be an extra unquoted colon in the line
and this is confusing the parser. It was only expecting to find one free
colon. The solution is just add some quotes around the colon, or quote the
entire line after the first colon.
However, it is not easy to fix, and I've tried quoting it in every way I can think of, to no avail.
It's a YAML limitation; the parser likely wants to either see a name, colon, and name=value pairs with no more colons on the line, or just name, colon, and 1 quoted string value.
The lineinfile doc has an example for sudoers mentioning this (and another one further down that doesn't work...) and it references YAML as the problem. This means any time you need to have a colon in a value you may as well quote the entire string of arguments just to save yourself the debugging hassle.
I made it work with this quoting:
lineinfile: "dest='/usr/local/lib/python2.7/ctypes/__init__.py' regexp='^#?CFUNCTYPE(c_int)(lambda: None)' line='# CFUNCTYPE(c_int)(lambda: None)'"
In order to ignore a file that doesn't exist, I used this code:
- stat: path=/usr/local/lib/python2.7/ctypes/__init__.py
register: init
- name: fix ctypes file
replace: "dest='/usr/local/lib/python2.7/ctypes/__init__.py' regexp='^( CFUNCTYPE.c_int..lambda: None.)' replace=' # CFUNCTYPE(c_int)(lambda: None)'"
when: init.stat.exists == True
sudo: yes
I also had to change lineinfile to replace, because the line is prefixed with 4 spaces, and I couldn't get it to match correctly.

Resources